Survey
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Chapter 9 Summary Software reuse reduces program-development time. The direct superclass of a subclass (specified by the keyword extends in the first line of a class declaration) is the superclass from which the subclass inherits. An indirect superclass of a subclass is two or more levels up the class hierarchy from that subclass. class HourlyEmployee extends Employee In single inheritance, a class is derived from one direct superclass. In multiple inheritance, a class is derived from more than one direct superclass. Java does not support multiple inheritance. A subclass is more specific than its superclass and represents a smaller group of objects. Every object of a subclass is also an object of that class's superclass. However, a superclass object is not an object of its class's subclasses. HourlyEmployee “is-a” Employee is ok. However, Employee “is-a” HourlyEmployee is NOT ok. An "is-a" relationship represents inheritance. In an "is-a" relationship, an object of a subclass also can be treated as an object of its superclass. A "has-a" relationship represents composition. In a "has-a" relationship, a class object contains references to objects of other classes. An examply of composition would be an Employee class containing String class objects. We would say that Employee “has-a” String A subclass cannot access or inherit the private members of its superclass—allowing this would violate the encapsulation of the superclass. A subclass can, however, inherit the non-private members of its superclass. Some say that with inheritance, everything is inherited but the way you can access what you have inherited depends on the access specifier used in the declaration of the member. Public members are directly accessible. Private members that are “inherited” can only be accessed using a public method that was also inherited. A superclass method can be overridden in a subclass to declare an appropriate implementation for the subclass. Overriding a method is done when a method is declared in a subclass with the same method header as a method in a superclass. Single-inheritance relationships form tree-like hierarchical structures—a superclass exists in a hierarchical relationship with its subclasses. A superclass's public members are accessible wherever the program has a reference to an object of that superclass or one of its subclasses. A superclass's private members are accessible only within the declaration of that superclass. A superclass's protected members have an intermediate level of protection between public and private access. They can be accessed by members of the superclass, by members of its subclasses and by members of other classes in the same package. The first task of any subclass constructor is to call its direct superclass's constructor, either explicitly (manually) or implicitly (automatically), to ensure that the instance variables inherited from the superclass are initialized properly. A subclass can explicitly invoke a constructor of its superclass by using the superclass constructor call syntax—keyword super, followed by a set of parentheses containing the superclass constructor arguments. super(arg1, arg2, … ); When a subclass method overrides a superclass method, the superclass method can be accessed from the subclass if the superclass method name is preceded by the keyword super and a dot (.) separator. super.toString( ) Declaring instance variables private, while providing non-private methods to manipulate and perform validation, helps enforce good software engineering. Method toString takes no arguments and returns a String. The Object class's toString method is normally overridden by a subclass. When an object is output using the %s format specifier, the object's toString method is called implicitly to obtain its string representation. Access to Class Members [ From the Java Tutorial ] Access Levels Modifier Class Package Subclass World public Y Y Y Y protected Y Y Y N no modifier [ package ] Y Y N N private Y N N N The first data column indicates whether the class itself has access to the member defined by the access level. As you can see, a class always has access to its own members. The second column indicates whether classes in the same package as the class (regardless of their parentage) have access to the member. The third column indicates whether subclasses of the class — declared outside this package — have access to the member. The fourth column indicates whether all classes have access to the member. Access levels affect you in two ways. First, when you use classes that come from another source, such as the classes in the Java platform, access levels determine which members of those classes your own classes can use. Second, when you write a class, you need to decide what access level every member variable and every method in your class should have. Chapter 10 Summary With polymorphism, it is possible to design and implement systems that are more easily extensible. Programs can be written to process objects of types that may not exist when the program is under development. There are many situations in which it is useful to declare abstract classes for which the programmer never intends to create objects. These are used only as superclasses, so we sometimes refer to them as abstract superclasses. You cannot instantiate objects of an abstract class. Classes from which objects can be created are called concrete classes. A class must be declared abstract if one or more of its methods are abstract. An abstract method is one with the keyword abstract to the left of the return type in its declaration. public abstract double getEarnings( ); If a class extends a class with an abstract method and does not provide a concrete implementation of that method, then that method remains abstract in the subclass. Consequently, the subclass is also an abstract class and must be declared abstract. Java enables polymorphism—the ability for objects of different classes related by inheritance or interface implementation to respond differently to the same method call. When a request is made through a superclass reference to a subclass object to use an abstract method, Java executes the implemented version of the method found in the subclass. Although we cannot instantiate objects of abstract classes, we can declare variables of abstractclass types. Such variables can be used to reference subclass objects. Suppose class Employee is an abstract class: public abstract class Employee Inside a different class, we could declare a reference variable of type Employee: Employee e; Due to dynamic binding (also called late binding), the specific type of a subclass object need not be known at compile time for a method call of a superclass variable to be compiled. At execution time, the correct subclass version of the method is called, based on the type of the reference stored in the superclass variable. Operator instanceof checks the type of the object to which its left operand refers and determines whether this type has an “is-a” relationship with the type specified as its right operand. If the two have an “is-a” relationship, the instanceof expression is true. If not, the instanceof expression is false. HourlyEmployee empX; empX instanceof HourlyEmployee Every object in Java knows its own class and can access this information through method getClass, which all classes inherit from class Object. Method getClass returns an object of type Class (package java.lang), which contains information about the object's type that can be accessed using Class's public methods. Class method getName, for example, returns the name of the class. Given x is an object reference variable class as a String. would return True. x.getClass().getName() would return the name of the An interface declaration begins with the keyword interface and contains a set of public abstract methods. Interfaces may also contain public static final fields. public interface Comparable To use an interface, a class must specify that it implements the interface and must either declare every method in the interface with the signatures specified in the interface declaration or be declared abstract. public class Employee implements Comparable An interface is typically used when disparate (i.e., unrelated) classes need to provide common functionality (i.e., methods) or use common constants. An interface is often used in place of an abstract class when there is no default implementation to inherit. When a class implements an interface, it establishes an “is-a” relationship with the interface type, as do all its subclasses. To implement more than one interface, simply provide a comma-separated list of interface names after keyword implements in the class declaration. public class Employee extends Object implements Comparable, Serializable Chapter 11 Summary A graphical user interface (GUI) presents a user-friendly mechanism for interacting with an application. A GUI gives an application a distinctive "look" and "feel." Providing different applications with consistent, intuitive user interface components allows users to be somewhat familiar with an application, so that they can learn it more quickly. GUIs are built from GUI components—sometimes called controls or widgets. Most applications use windows or dialog boxes (also called dialogs) to interact with the user. Class JOptionPane (package javax.swing) provides prepackaged dialog boxes for both input and output. JOptionPane static method showInputDialog displays an input dialog. String response = JoptionPane.showInputDialog( ); A prompt typically uses sentence-style capitalization—a style that capitalizes only the first letter of the first word in the text unless the word is a proper noun. An input dialog can only input Strings. This is typical of most GUI components. JOptionPane static method showMessageDialog displays a message dialog. JoptionPane.showMessageDialog( ); Most Swing GUI components are located in package javax.swing. They are part of the Java Foundation Classes (JFC)—Java's libraries for cross-platform GUI development. Together, the appearance and the way in which the user interacts with the application are known as that application's look-and-feel. Swing GUI components allow you to specify a uniform look-and-feel for your application across all platforms or to use each platform's custom look-and-feel. Lightweight Swing components are not tied to actual GUI components supported by the underlying platform on which an application executes. Several Swing components are heavyweight components that require direct interaction with the local windowing system, which may restrict their appearance and functionality. Class Component (package java.awt) declares many of the attributes and behaviors common to the GUI components in packages java.awt and javax.swing. Class Container (package java.awt) is a subclass of Component. Components are attached to Containers so the Components can be organized and displayed on the screen. Also a Container “is-a” Component. Class JComponent (package javax.swing) is a subclass of Container. JComponent is the superclass of all lightweight Swing components and declares their common attributes and behaviors. Some common JComponent features include a pluggable look-and-feel, shortcut keys called mnemonics, tool tips, support for assistive technologies and support for user interface localization. Most windows are instances of class JFrame or a subclass of JFrame. JFrame provides the basic attributes and behaviors of a window. A JLabel displays a single line of read-only text, an image, or both text and an image. Text in a JLabel normally uses sentence-style capitalization. When building a GUI, each GUI component must be added to a container, such as a window created with a JFrame. Many IDEs provide GUI design tools in which you can specify the exact size and location of a component by using the mouse, then the IDE will generate the GUI code for you. This would be explicity “laying out” an object rather than allowing this to be done using a layout manager. JComponent method setToolTipText specifies the tool tip that is displayed when the user positions the mouse cursor over a lightweight component. Container method add attaches a GUI component to a Container. Class ImageIcon (package javax.swing) supports several image formats, including Graphics Interchange Format (GIF), Portable Network Graphics (PNG) and Joint Photographic Experts Group (JPEG). Method getClass (of class Object) retrieves a reference to the Class object that represents the the class declaration for the object on which the method is called. Class method getResource returns the location of its argument as a URL. Method getResource uses the Class object's class loader to determine the location of the resource. Interface SwingConstants (package javax.swing) declares a set of common integer constants that are used with many Swing components. The horizontal and vertical alignments of a JLabel can be set with methods setHorizontalAlignment and setVerticalAlignment, respectively. JLabel method setText sets the text displayed on a label. The corresponding method getText retrieves the current text displayed on a label. JLabel method setIcon specifies the Icon to display on a label. The corresponding method getIcon retrieves the current Icon displayed on a label. JLabel methods setHorizontalTextPosition and setVerticalTextPosition specify the text position in the label. JFrame method setDefaultCloseOperation with constant JFrame.EXIT_ON_CLOSE as the argument indicates that the program should terminate when the window is closed by the user. Component method setSize specifies the width and height of a component. Component method setVisible with the argument true displays a JFrame on the screen. GUIs are event driven—when the user interacts with a GUI component, events drive the program to perform tasks. The code that performs a task in response to an event is called an event handler and the overall process of responding to events is known as event handling. Class JTextField extends class JTextComponent (package javax.swing.text), which provides many features common to Swing's text-based components. Class JPasswordField extends JTextField and adds several methods that are specific to processing passwords. A component receives the focus when the user clicks the component. Before an application can respond to an event for a particular GUI component, you must perform several coding steps: (1) Create a class that represents the event handler. (2) Implement an appropriate interface, known as an event-listener interface, in the class from Step 1. (3) Indicate that an object of the class from Steps 1 and 2 should be notified when the event occurs. This is known as registering the event handler. Java allows you to declare nested classes inside other classes. Nested classes can be static or non-static. Non-static nested classes are called inner classes and are frequently used for event handling. Before an object of an inner class can be created, there must first be an object of the top-level class that contains the inner class, because an inner-class object implicitly has a reference to an object of its top-level class. An inner-class object is allowed to directly access all the instance variables and methods of its top-level class. A nested class that is static does not require an object of its top-level class and does not implicitly have a reference to an object of the top-level class. When the user presses Enter in a JTextField or JPasswordField, the GUI component generates an ActionEvent (package java.awt.event). Such an event is processed by an object that implements the interface ActionListener (package java.awt.event). JTextField method addActionListener registers the event handler for a component text field. This method receives as its argument an ActionListener object. The GUI component with which the user interacts is the event source. An ActionEvent object contains information about the event that just occurred, such as the event source and the text in the text field. ActionEvent method getSource returns a reference to the event source. ActionEvent method getActionCommand returns the text the user typed in a text field or the label on a JButton. JPasswordField method getPassword returns the password the user typed. For each event-object type, there is typically a corresponding event-listener interface. Each event-listener interface specifies one or more event-handling methods that must be declared in the class that implements the interface. When an event occurs, the GUI component with which the user interacted notifies its registered listeners by calling each listener's appropriate event-handling method. Every JComponent has an instance variable called listenerList that refers to an object of class EventListenerList (package javax.swing.event). Each object of a JComponent subclass maintains a references to all of its registered listeners in the listenerList. Every GUI component supports several event types, including mouse events, key events and others. When an event occurs, the event is dispatched only to the event listeners of the appropriate type. The GUI component receives a unique event ID specifying the event type, which it uses to decide the listener type to which the event should be dispatched and which method to call on each listener object. Command buttons are created with class JButton. A JButton can display an Icon. To provide the user with an extra level of visual interaction with the GUI, a JButton can also have a rollover Icon—an Icon that is displayed when the user positions the mouse over the button. The Swing GUI components contain three types of state buttons—JToggleButton, JCheckBox and JRadioButton. Classes JCheckBox and JRadioButton are subclasses of JToggleButton. A JRadioButton is different from a JCheckBox in that normally several JRadioButtons are grouped together, and only one in the group can be selected at any time. Method setFont (of class Component) sets the font of a component to a new object of class Font (package java.awt). When the user clicks a JCheckBox, an ItemEvent occurs. This event can be handled by an ItemListener object, which must implement method itemStateChanged. Method addItemListener registers the listener for a JCheckBox or JRadioButton object. JCheckBox method isSelected determines if a JCheckBox is selected. JRadioButtons are similar to JCheckBoxes in that they have two states—selected and not selected. However, radio buttons normally appear as a group in which only one button can be selected at a time. Selecting a different radio button forces all others to be deselected. JRadioButtons are used to represent mutually exclusive options. The logical relationship between JRadioButtons is maintained by a ButtonGroup object (package javax.swing). ButtonGroup method add associates each a JRadioButton with a ButtonGroup. If more than one selected JRadioButton object is added to a group, the selected one that was added first will be selected when the GUI is displayed. JRadioButtons generate ItemEvents when they are clicked. A JComboBox provides a list of items from which the user can make a single selection. JComboBoxes generate ItemEvents. Each item in a JComboBox has an index. The first item added to a JComboBox appears as the currently selected item when the JComboBox is displayed. Other items are selected by clicking the JComboBox, which expands into a list from which the user can make a selection. An anonymous inner class is a special form of inner class that is declared without a name and typically appears inside a method declaration. Since an anonymous inner class has no name, one object of the anonymous inner class must be created at the point where the class is declared. JComboBox method getSelectedIndex returns the index of the selected item. A JList displays a series of items from which the user may select one or more items. Class JList supports single-selection lists and multiple-selection lists. When the user clicks an item in a JList, a ListSelectionEvent occurs. JList method addListSelectionListener registers a ListSelectionListener for a JList's selection events. A ListSelectionListener (package javax.swing.event) must implement method valueChanged. A JList does not provide a scrollbar if there are more items in the list than the number of visible rows. In this case, a JScrollPane object can be used to provide the scrolling capability. JFrame method getContentPane returns a reference to the JFrame's content pane where GUI components are displayed. JList method getSelectedIndex returns the selected item's index. Many event-listener interfaces contain multiple methods. For many of these interfaces, packages java.awt.event and javax.swing.event provide event-listener adapter classes. An adapter class implements an interface and provides a default implementation of each method in the interface ( an emply method body… { } ). You can extend an adapter class to inherit the default implementation of every method and subsequently override only the method(s) you need for event handling. Lightweight Swing components that extend class JComponent contain method paintComponent, which is called when a lightweight Swing component is displayed. By overriding this method, you can specify how to draw shapes using Java's graphics capabilities. When customizing a JPanel for use as a dedicated drawing area, the subclass should override method paintComponent and call the superclass version of paintComponent as the first statement in the body of the overridden method. Subclasses of JComponent support transparency. When a component is opaque, paintComponent clears the component's background before the component is displayed. The transparency of a Swing lightweight component can be set with method setOpaque (a false argument indicates that the component is transparent). Class Point (package java.awt) represents an x-y coordinate. Class Graphics is used to draw. Method repaint (inherited indirectly from class Component) indicates that a component should be refreshed on the screen as soon as possible. Method paintComponent receives a Graphics parameter and is called automatically any time a lightweight component needs to be displayed on the screen. Graphics method fillOval draws a solid oval. The method's four parameters represent the bounding box in which the oval is displayed. The first two parameters are the upper-left x-coordinate and the upper-left ycoordinate of the rectangular area. The last two coordinates represent the rectangular area's width and Layout managers arrange GUI components in a container for presentation purposes. All layout managers implement the interface LayoutManager (package java.awt). Container method setLayout specifies the layout of a container. FlowLayout is the simplest layout manager. GUI components are placed on a container from left to right in the order in which they are added to the container. When the edge of the container is reached, components continue to display on the next line. Class FlowLayout allows GUI components to be left aligned, centered (the default) and right aligned. FlowLayout method setAlignment changes the alignment for a FlowLayout. The BorderLayout layout manager (the default for a JFrame) arranges components into five regions: NORTH, SOUTH, EAST, WEST and CENTER. NORTH corresponds to the top of the container. A BorderLayout limits a Container to containing at most five components—one in each region. The GridLayout layout manager divides the container into a grid so that components can be placed in rows and columns. Container method validate recomputes a container's layout based on the current layout manager for the Container and the current set of displayed GUI components. A JTextArea provides an area for manipulating multiple lines of text. JTextArea is a subclass of JTextComponent, which declares common methods for JTextFields, JTextAreas and several other text-based GUI components. Class Box is a subclass of Container that uses a BoxLayout layout manager to arrange the GUI components either horizontally or vertically. Box static method createHorizontalBox creates a Box that arranges components from left to right in the order that they are attached. Method getSelectedText (inherited into JTextArea from JTextComponent) returns the selected text from a JTextArea. // Fig. 11.2: Addition.java // Addition program that uses JOptionPane for input and output. import javax.swing.JOptionPane; // program uses JOptionPane public class Addition { public static void main( String args[] ) { // obtain user input from JOptionPane input dialogs String firstNumber = JOptionPane.showInputDialog( "Enter first integer" ); String secondNumber = JOptionPane.showInputDialog( "Enter second integer" ); // convert String inputs to int values for use in a calculation int number1 = Integer.parseInt( firstNumber ); int number2 = Integer.parseInt( secondNumber ); int sum = number1 + number2; // add numbers // display result in a JOptionPane message dialog JOptionPane.showMessageDialog( null, "The sum is " + sum, "Sum of Two Integers", JOptionPane.INFORMATION_MESSAGE ); } // end method main } // end class Addition // Fig. 11.6: LabelFrame.java ************************************************** // Demonstrating the JLabel class. import java.awt.FlowLayout; // specifies how components are arranged import javax.swing.JFrame; // provides basic window features import javax.swing.JLabel; // displays text and images import javax.swing.SwingConstants; // common constants used with Swing import javax.swing.Icon; // interface used to manipulate images import javax.swing.ImageIcon; // loads images public class LabelFrame extends JFrame { private JLabel label1; // JLabel with just text private JLabel label2; // JLabel constructed with text and icon private JLabel label3; // JLabel with added text and icon // LabelFrame constructor adds JLabels to JFrame public LabelFrame() { super( "Testing JLabel" ); setLayout( new FlowLayout() ); // set frame layout // JLabel constructor with a string argument label1 = new JLabel( "Label with text" ); label1.setToolTipText( "This is label1" ); add( label1 ); // add label1 to JFrame // JLabel constructor with string, Icon and alignment arguments Icon bug = new ImageIcon( getClass().getResource( "bug1.gif" ) ); label2 = new JLabel( "Label with text and icon", bug, SwingConstants.LEFT ); label2.setToolTipText( "This is label2" ); add( label2 ); // add label2 to JFrame label3 = new JLabel(); // JLabel constructor no arguments label3.setText( "Label with icon and text at bottom" ); label3.setIcon( bug ); // add icon to JLabel label3.setHorizontalTextPosition( SwingConstants.CENTER ); label3.setVerticalTextPosition( SwingConstants.BOTTOM ); label3.setToolTipText( "This is label3" ); add( label3 ); // add label3 to JFrame } // end LabelFrame constructor } // end class LabelFrame // Fig. 11.7: LabelTest.java ***************************************************** import javax.swing.JFrame; public class LabelTest { public static void main( String args[] ) { LabelFrame labelFrame = new LabelFrame(); // create LabelFrame labelFrame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); labelFrame.setSize( 275, 180 ); // set frame size labelFrame.setVisible( true ); // display frame } // end main } // end class LabelTest // Fig. 11.19: RadioButtonFrame.java ******************************************* // Creating radio buttons using ButtonGroup and JRadioButton. import java.awt.FlowLayout; import java.awt.Font; import java.awt.event.ItemListener; import java.awt.event.ItemEvent; import javax.swing.JFrame; import javax.swing.JTextField; import javax.swing.JRadioButton; import javax.swing.ButtonGroup; public class RadioButtonFrame extends JFrame { private JTextField textField; // used to display font changes private Font plainFont; // font for plain text private Font boldFont; // font for bold text private Font italicFont; // font for italic text private Font boldItalicFont; // font for bold and italic text private JRadioButton plainJRadioButton; // selects plain text private JRadioButton boldJRadioButton; // selects bold text private JRadioButton italicJRadioButton; // selects italic text private JRadioButton boldItalicJRadioButton; // bold and italic private ButtonGroup radioGroup; // buttongroup to hold radio buttons // RadioButtonFrame constructor adds JRadioButtons to JFrame public RadioButtonFrame() { super( "RadioButton Test" ); setLayout( new FlowLayout() ); // set frame layout textField = new JTextField( "Watch the font style change", 25 ); add( textField ); // add textField to JFrame // create radio buttons plainJRadioButton = new JRadioButton( "Plain", true ); boldJRadioButton = new JRadioButton( "Bold", false ); italicJRadioButton = new JRadioButton( "Italic", false ); boldItalicJRadioButton = new JRadioButton( "Bold/Italic", false ); add( plainJRadioButton ); // add plain button to JFrame add( boldJRadioButton ); // add bold button to JFrame add( italicJRadioButton ); // add italic button to JFrame add( boldItalicJRadioButton ); // add bold and italic button // create logical relationship between JRadioButtons radioGroup = new ButtonGroup(); // create ButtonGroup radioGroup.add( plainJRadioButton ); // add plain to group radioGroup.add( boldJRadioButton ); // add bold to group radioGroup.add( italicJRadioButton ); // add italic to group radioGroup.add( boldItalicJRadioButton ); // add bold and italic // create font objects plainFont = new Font( "Serif", Font.PLAIN, 14 ); boldFont = new Font( "Serif", Font.BOLD, 14 ); italicFont = new Font( "Serif", Font.ITALIC, 14 ); boldItalicFont = new Font( "Serif", Font.BOLD + Font.ITALIC, 14 ); textField.setFont( plainFont ); // set initial font to plain // register events for JRadioButtons plainJRadioButton.addItemListener( new RadioButtonHandler( plainFont ) ); boldJRadioButton.addItemListener( new RadioButtonHandler( boldFont ) ); italicJRadioButton.addItemListener( new RadioButtonHandler( italicFont ) ); boldItalicJRadioButton.addItemListener( new RadioButtonHandler( boldItalicFont ) ); } // end RadioButtonFrame constructor // private inner class to handle radio button events private class RadioButtonHandler implements ItemListener { private Font font; // font associated with this listener public RadioButtonHandler( Font f ) { font = f; // set the font of this listener } // end constructor RadioButtonHandler // handle radio button events public void itemStateChanged( ItemEvent event ) { textField.setFont( font ); // set font of textField } // end method itemStateChanged } // end private inner class RadioButtonHandler } // end class RadioButtonFrame // Fig. 11.20: RadioButtonTest.java *********************************************** // Testing RadioButtonFrame. import javax.swing.JFrame; public class RadioButtonTest { public static void main( String args[] ) { RadioButtonFrame radioButtonFrame = new RadioButtonFrame(); radioButtonFrame.setDefaultCloseOperation( JFrame.EXIT_ON_CLOSE ); radioButtonFrame.setSize( 300, 100 ); // set frame size radioButtonFrame.setVisible( true ); // display frame } // end main } // end class RadioButtonTest Chapter 13 Summary An exception is an indication of a problem that occurs during a program's execution. Exception handling enables programmers to create applications that can resolve exceptions. Exception handling enables programmers to remove error-handling code from the "main line" of the program's execution, improving program clarity and enhancing modifiability. Exceptions are thrown when a method detects a problem and is unable to handle it. An exception's stack trace includes the name of the exception in a descriptive message that indicates the problem that occurred and the complete method-call stack (i.e., the call chain) at the time the exception occurred. The point in the program at which an exception occurs is called the throw point. A try block encloses the code that might throw an exception and the code that should not execute if that exception occurs. Exceptions may surface through: o o o explicitly mentioned code in a try block, through calls to other methods or even through deeply nested method calls initiated by code in the try block. A catch block begins with the keyword catch and an exception parameter followed by a block of code that catches (i.e., receives) and handles the exception. This code executes when the try block detects the exception. An uncaught exception is an exception that occurs for which there are no matching catch blocks. An uncaught exception will cause a program to terminate early if that program contains only one thread. If the program contains more than one thread, only the thread where the exception occurred will terminate. The rest of the program will run, but may yield adverse effects. At least one catch block or a finally block must immediately follow the try block. Each catch block specifies in parentheses an exception parameter that identifies the exception type the handler can process. The exception parameter's name enables the catch block to interact with a caught exception object. If an exception occurs in a try block, the try block terminates immediately and program control transfers to the first of the following catch blocks whose exception parameter type matches the type of the thrown exception. After an exception is handled, program control does not return to the throw point because the try block has expired. This is known as the termination model of exception handling. If there are multiple matching catch blocks when an exception occurs, only the first is executed. After executing a catch block, this program's flow of control proceeds to the first statement after the last catch block. A throws clause specifies the exceptions the method throws, and appears after the method's parameter list and before the method body. public void readRecords( ) throws FileNotFoundException The throws clause contains a comma-separated list of exceptions that the method will throw if a problem occurs when the method executes. Exception handling is designed to process synchronous errors, which occur when a statement executes. Exception handling is not designed to process problems associated with asynchronous events, which occur in parallel with, and independent of, the program's flow of control. All Java exception classes inherit, either directly or indirectly, from class Exception. Because of this fact, Java's exception classes form a hierarchy. Programmers can extend this hierarchy to create their own exception classes. Class Throwable is the superclass of class Exception, and is therefore also the superclass of all exceptions. Only Throwable objects can be used with the exception-handling mechanism. Class Throwable has two subclasses: Exception and Error. Class Exception and its subclasses represent exceptional situations that could occur in a Java program and be caught by the application. Class Error and its subclasses represent exceptional situations that could happen in the Java runtime system. Errors happen infrequently, and typically should not be caught by an application. Java distinguishes between two categories of exceptions: checked and unchecked. Unlike checked exceptions, the Java compiler does not check the code to determine whether an unchecked exception is caught or declared. Unchecked exceptions typically can be prevented by proper coding. An exception's type determines whether the exception is checked or unchecked. All exception types that are direct or indirect subclasses of class RuntimeException are unchecked exceptions. All exception types that inherit from class Exception but not from RuntimeException are checked. Various exception classes can be derived from a common superclass. If a catch block is written to catch exception objects of a superclass type, it can also catch all objects of that class's subclasses. This allows for polymorphic processing of related exceptions. Programs that obtain certain types of resources must return them to the system explicitly to avoid so-called resource leaks. Resource-release code typically is placed in a finally block. The finally block is optional. If it is present, it is placed after the last catch block. Java guarantees that a provided finally block will execute whether or not an exception is thrown in the corresponding try block or any of its corresponding catch blocks. Java also guarantees that a finally block executes if a try block exits by using a return, break or continue statement. If an exception that occurs in the try block cannot be caught by one of that try block's associated catch handlers, the program skips the rest of the try block and control proceeds to the finally block, which releases the resource. Then the program passes to the next outer try block—normally in the calling method. If a catch block throws an exception, the finally block still executes. Then the exception is passed to the next outer try block—normally in the calling method. Programmers can throw exceptions by using the throw statement. throw new Exception( ); A throw statement specifies an object to be thrown. The operand of a throw can be of any class derived from class Throwable. Exceptions are rethrown when a catch block, upon receiving an exception, decides either that it cannot process that exception or that it can only partially process it. Rethrowing an exception defers the exception handling (or perhaps a portion of it) to another catch block. When a rethrow occurs, the next enclosing try block detects the rethrown exception, and that try block's catch blocks attempt to handle the exception. When an exception is thrown but not caught in a particular scope, the method-call stack is unwound, and an attempt is made to catch the exception in the next outer try statement. This process is called stack unwinding. Class Throwable offers a printStackTrace method that prints the method-call stack. Often, this is helpful in testing and debugging. Class Throwable also provides a getStackTrace method that obtains stack-trace information printed by printStackTrace. Class Throwable's getMessage method returns the descriptive string stored in an exception. A new exception class must extend an existing exception class to ensure that the class can be used with the exception-handling mechanism. // Fig. 13.5: UsingExceptions.java **************************************************** // Demonstration of the try...catch...finally exception handling // mechanism. public class UsingExceptions { public static void main( String args[] ) { try { throwException(); // call method throwException } // end try catch ( Exception exception ) // exception thrown by throwException { System.err.println( "Exception handled in main" ); } // end catch doesNotThrowException(); } // end main // demonstrate try...catch...finally public static void throwException() throws Exception { try // throw an exception and immediately catch it { System.out.println( "Method throwException" ); throw new Exception(); // generate exception } // end try catch ( Exception exception ) // catch exception thrown in try { System.err.println( "Exception handled in method throwException" ); throw exception; // rethrow for further processing // exception rethrown in catch } // end catch finally // executes regardless of what occurs in try...catch { System.err.println( "Finally executed in throwException" ); } // end finally // any code here would not be reached } // end method throwException // demonstrate finally when no exception occurs public static void doesNotThrowException() { try // try block does not throw an exception { System.out.println( "Method doesNotThrowException" ); } // end try catch ( Exception exception ) // does not execute { System.err.println( exception ); } // end catch finally // executes regardless of what occurs in try...catch { System.err.println( "Finally executed in doesNotThrowException" ); } // end finally System.out.println( "End of method doesNotThrowException" ); } // end method doesNotThrowException } // end class UsingExceptions //Program Output Method throwException Exception handled in method throwException Finally executed in throwException Exception handled in main Method doesNotThrowException Finally executed in doesNotThrowException End of method doesNotThrowException Chapter 14 Summary Data stored in variables and arrays is temporary—the data is lost when a local variable goes out of scope or when the program terminates. Computers use files for long-term retention of large amounts of data, even after the programs that created the data terminate. Persistent data maintained in files exists beyond the duration of program execution. Computers store files on secondary storage devices such as hard disks. The smallest data item in a computer can assume the value 0 or the value 1 and is called a bit. Ultimately, a computer processes all data items as combinations of zeros and ones. The computer's character set is the set of all characters used to write programs and represent data. Characters in Java are Unicode characters composed of two bytes, each composed of eight bits. Just as characters are composed of bits, fields are composed of characters or bytes. A field is a group of characters or bytes that conveys meaning. Data items processed by computers form a data hierarchy that becomes larger and more complex in structure as we progress from bits to characters to fields, and so on. Typically, several fields compose a record (implemented as a class in Java). A record is a group of related fields. A file is a group of related records. To facilitate the retrieval of specific records from a file, at least one field in each record is chosen as a record key. A record key identifies a record as belonging to a particular person or entity and is unique to each record. There are many ways to organize records in a file. The most common is called a sequential file, in which records are stored in order by the record-key field. A group of related files is often called a database. A collection of programs designed to create and manage databases is called a database management system (DBMS). Java views each file as a sequential stream of bytes. Every operating system provides a mechanism to determine the end of a file, such as an end-of-file marker or a count of the total bytes in the file that is recorded in a system-maintained administrative data structure. Byte-based streams represent data in binary format. Character-based streams represent data as sequences of characters. Files that are created using byte-based streams are binary files. Files created using character-based streams are text files. Text files can be read by text editors, whereas binary files are read by a program that converts the data to a human-readable format. Java also can associate streams with different devices. Three stream objects are associated with devices when a Java program begins executing—System.in, System.out and System.err. The java.io package includes definitions for stream classes, such as FileInputStream (for byte-based input from a file), FileOutputStream (for byte-based output to a file), FileReader (for character-based input from a file) and FileWriter (for character-based output to a file). Files are opened by creating objects of these stream classes. Class File is used to obtain information about files and directories. Character-based input and output can be performed with classes Scanner and Formatter. Class Formatter enables formatted data to be output to the screen or to a file in a manner similar to System.out.printf. A separator character is used to separate directories and files in the path. Java imposes no structure on a file—notions such as a record do not exist as part of the Java language. The programmer must structure files to meet an application's requirements. To retrieve data sequentially from a file, programs normally start reading from the beginning of the file and read all the data consecutively until the desired information is found. Data in many sequential files cannot be modified without the risk of destroying other data in the file. Therefore, records in a sequential-access file are not usually updated in place. Instead, the entire file is usually rewritten. Java provides a mechanism called object serialization that enables entire objects to be written to or read from a stream. A serialized object is an object represented as a sequence of bytes that includes the object's data as well as information about the object's type and the types of data stored in the object. After a serialized object has been written into a file, it can be read from the file and deserialized—that is, the type information and bytes that represent the object and its data can be used to re-create the object in memory. Classes ObjectInputStream and ObjectOutputStream, which respectively implement the ObjectInput and ObjectOutput interfaces, enable entire objects to be read from or written to a stream (possibly a file). Only classes that implement interface Serializable can be serialized and deserialized with ObjectOutputStreams and ObjectInputStreams. The ObjectOutput interface contains method writeObject, which takes an Object that implements interface Serializable as an argument and writes its information to an OutputStream. The ObjectInput interface contains method readObject, which reads and returns a reference to an Object from an InputStream. After an object has been read, its reference can be cast to the object's actual type. Instant record access is possible with random-access files and with databases. A program can access individual records of a random-access file directly (and quickly) without searching through other records. Random-access files are sometimes called direct-access files. Using fixed-length records makes it easy for a program to calculate (as a function of the record size and the record key) the exact location of any record relative to the beginning of the file. When a program associates an object of class RandomAccessFile with a file, the program reads or writes data, beginning at the location in the file specified by the file-position pointer, and manipulates all the data as primitive types. RandomAccessFile method seek positions to the exact location in the file at which a record of information is stored. Method seek sets the file-position pointer to a specific location in the file relative to the beginning of the file. Buffering is an I/O-performance-enhancement technique. With a BufferedOutputStream, each output statement does not necessarily result in an actual physical transfer of data to the output device. Rather, each output operation is directed to a region in memory called a buffer that is large enough to hold the data of many output operations. Actual transfer to the output device is then performed in one large physical output operation each time the buffer fills. Input / Output in Java Input/Output in Java can be done using the console or using files. These two types of I/O will be discussed below. An object is always needed to perform an input/output operation in Java. Console Input/Output Using a Scanner object layered on the System.in object for input and the standard output object System.out for output Input: 1. Use the Scanner class to create an input object using the standard input object in the System class ( System.in ). The System.in object is an InputStream object. Scanner input = new Scanner( System.in ); 2. Use Scanner class methods to get values the user enters using the keyboard. int num1, num2, num3; … num1 = input.nextInt(); num2 = input.nextInt(); num3 = input.nextInt(); Output: 1. Use the standard output object in the System class ( System.out ). 2. Use PrintStream class methods ( print(), printf(), println() ) to display the output to the screen using the System.out object. The System.out object is a PrintStream object. int sum = num1 + num2 + num3; System.out.printf("The sum of the numbers is %5d%n", sum); File Input/Output Using a Scanner object for input and a PrintWriter object for output. Note: Once we have created our objects, the input/output statements look virtually identical to the versions using the keyboard and screen. Input: 1. Use the Scanner class to create a new input object using a File object. Scanner inputFile = new Scanner( new File("MyData.txt") ); The MyData.txt file can be created using a simple editor such as Notepad. If the input file can not be found at runtime, an exception will occur and your program will stop execution. 2. Use Scanner class methods to read values from the input file. int num1, num2, num3; … num1 = inputFile.nextInt(); num2 = inputFile.nextInt(); num3 = inputFile.nextInt(); Output: 1. Create a PrintWriter object. The PrintWriter class is a subclass of PrintStream. The methods print(), printf(), println() will be inherited for use when a PrintWriter object is created. PrintWriter outputFile = new PrintWriter("MyReport.txt"); The output file will automatically be created by your program. If a file exists with that name, it will be overwritten. 2. Use PrintWriter class methods ( print(), printf(), println() ) to write the output to the file using the PrintWriter object. int sum = num1 + num2 + num3; outputFile.printf("The sum of the numbers is %5d%n", sum); Note for File Input/Output, you need to close the file when you are finished doing your input or output operations. The close( ) method is used to do this. Close the input file object: inputFile.close(); Close the output file object: outputFile.close(); Also, because an input file may not be found at runtime, you must include the clause throws FileNotFoundException at the end of the method in which you create your input file object. You will see this at the end of method main in the Java program that follows. It may also be required at the end of other methods if you do not create the object in method main – see the examples I have provided. To get access to the file stream and exception classes necessary to do input, you must include an import statement that imports the classes in java.io. Use the following import statement at the beginning of your program in addition to the import statement for the Scanner class. import java.io.*; Note, the names your choose for your object references is entirely up to you. An identifier is used in the declaration of a reference. You must follow the same rules as for any identifier. Choose a name that is descriptive. Here are some example input file object identifiers: Here are some example input file object identifiers: inFile, inputFile, dataFile outFile, outputFile, reportFile Common Scanner Class methods used for Input hasNext() //something is available to be read nextInt() nextDouble() //get an int //get a double next() NextLine() //get a String ( delimited by whitespace ) //get the rest of the line as a String Sample Application to read input from a file and write output to a file. Suggestion: Use the txt extension for your input and output files. Input file: Output File: AccountData.txt AccountReport.txt The input file will contain three fields: an integer account number, a real account balance, a String account name. AccountData.txt contents: Note all the fields have been separated by whitespace characters ( space or newline ). 123 458 727 394 1358.72 Fred Flintstone 2283.59 Barney Rubble 100.00 Pebbles 100.00 Bam Bam Java Program to read the data file and add 10% to everbody's balance. import java.util.Scanner; import java.io.*; //access to Scanner class //access to file stream and exception classes public class UpdateBalance { public static void main( String args[] ) throws FileNotFoundException { int accountNumber; //create variables for the fields in the file double accountBalance; String accountName; Scanner inFile = new Scanner( new File( "AccountData.txt" ) ); PrintWriter outFile = new PrintWriter( "AccountReport.txt" ); while ( inFile.hasNext() ) //while there is data to process… { accountNumber = inFile.nextInt(); accountBalance = inFile.nextDouble(); accountName = inFile.nextLine(); accountBalance = accountBalance + ( accountBalance * .10 ); outFile.printf("%d %-18s $%,8.2f%n", accountNumber, accountName, accountBalance); } inFile.close(); outFile.close(); //close the files } } Contents of output file AccountReport.txt: 123 458 727 394 Fred Flintstone Barney Rubble Pebbles Bam Bam $1,494.59 $2,511.95 $ 110.00 $ 110.00 // Fig. 14.11: ReadTextFile.java // This program reads a text file and displays each record. import java.io.File; import java.io.FileNotFoundException; import java.lang.IllegalStateException; import java.util.NoSuchElementException; import java.util.Scanner; import com.deitel.jhtp6.ch14.AccountRecord; public class ReadTextFile { private Scanner input; // enable user to open file public void openFile() { try { input = new Scanner( new File( "clients.txt" ) ); } // end try catch ( FileNotFoundException fileNotFoundException ) { System.err.println( "Error opening file." ); System.exit( 1 ); } // end catch } // end method openFile // read record from file public void readRecords() { // object to be written to screen AccountRecord record = new AccountRecord(); System.out.printf( "%-10s%-12s%-12s%10s\n", "Account", "First Name", "Last Name", "Balance" ); try // read records from file using Scanner object { while ( input.hasNext() ) { record.setAccount( input.nextInt() ); // read account number record.setFirstName( input.next() ); // read first name record.setLastName( input.next() ); // read last name record.setBalance( input.nextDouble() ); // read balance // display record contents System.out.printf( "%-10d%-12s%-12s%10.2f\n", record.getAccount(), record.getFirstName(), record.getLastName(), record.getBalance() ); } // end while } // end try catch ( NoSuchElementException elementException ) { System.err.println( "File improperly formed." ); input.close(); System.exit( 1 ); } // end catch catch ( IllegalStateException stateException ) { System.err.println( "Error reading from file." ); System.exit( 1 ); } // end catch } // end method readRecords // close file and terminate application public void closeFile() { if ( input != null ) input.close(); // close file } // end method closeFile } // end class ReadTextFile // Fig. 14.12: ReadTextFileTest.java // This program test class ReadTextFile. public class ReadTextFileTest { public static void main( String args[] ) { ReadTextFile application = new ReadTextFile(); application.openFile(); application.readRecords(); application.closeFile(); } // end main } // end class ReadTextFileTest //Program Output Account 100 200 300 400 500 First Name Bob Steve Pam Sam Sue Last Name Jones Doe White Stone Rich Balance 24.98 -345.67 0.00 -42.16 224.62