Download Chapter 10.1

Survey
yes no Was this document useful for you?
   Thank you for your participation!

* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project

Document related concepts
no text concepts found
Transcript
Chapter 10: Exceptions and I/O
Streams
Original Slides by John Lewis and William Loftus
Modified significantly by
Bob Roggio, July 2007
1
Exceptions and I/O Streams
Now we can explore two related topics further:
exceptions and input/output streams
Chapter 8 focuses on:






Exception Handling
Uncaught Exceptions
The try-catch statement
The finally Clause
Exception propagation
The Exception Class Hierarchy
Checked and unchecked Exceptions


I/O Exceptions
I/O Streams
2/31
Exception Handling
An exception is an object that describes an unusual or erroneous
situation
Exceptions are thrown by a program or the runtime environment, and
may be caught and handled by another part of the program




This means that when an exception occurs, you can sometimes code
what you want to happen.
An exception is an object that defines unusual or erroneous
situations.
An exception is something that should not normally happen or
happen infrequently.
Your book has a list of common exceptions to be thrown.
Array index out of bounds; specified file cannot be found; division by zero, …
3/31
Exception Handling
As its name implies, exceptions are ‘exceptions’ to the
normal way of doing business and we can design efficient
ways to handle them if/when they occur.
Program can deal with an exception in one of three ways:



ignore it
handle it where it occurs
handle it an another place in the program
The manner in which an exception is processed is an
important design consideration
4/31
Exception Handling
If an exception is ignored by the program, the program will
terminate abnormally and produce an appropriate message
The message includes a call stack trace that indicates the line
on which the exception occurred

You have no doubt seen these!
The call stack trace also shows the method call trail that lead
to the attempted execution of the offending line


The getMessage method returns a string explaining why the
exception was thrown
The printStackTrace method prints the call stack trace
We will see these ahead.
5/31
Example: Uncaught Exception
// Zero.java
Author: Lewis/Loftus
public class Zero
{
First line says that Exception was thrown.
Other lines: Call trace (ahead)
// Deliberately divides by zero to produce an exception.
public static void main (String[] args)
{
int numerator = 10;
int denominator = 0;
System.out.println (numerator / denominator);
Call stack trace
problem
Exception class
Method, file, and line number
System.out.println ("This text will not be printed.");
where exception occurred.
}// end main()
}// end Zero
Output:
Exception in thread “main” java.lang.ArithmeticException: / by zero at Zero.main (Zero.java:17)
Note: tells problem and class.method where it occurred and statement number!
There’s no code to handle this exception explicitly. The second System.out.println does not
execute, because the exception occurs first.
First line says what exception was thrown and provides some info about why it was thrown.
Remaining lines are the call stack trace
6/31
Can call methods in exception class: getMessage returns a string explaining reason for exception
The try-catch Statement
To process an exception when it occurs, the line that can
cause (throw) an exception is executed within a try block
A try block is followed by one or more catch clauses,
which contain code to process an exception

The catch clauses are called exception handlers.
The try code is executed. If all is well, execution
continues following any catch clauses present.
If an exception occurs, processing continues at the first
catch clause that matches the exception type class.
Once the catch is executed, control returns to the next
statement following the last catch claus
7/31
public class ProductCodes // Author: Lewis / Loftus. Demo use of try-catch block.
{
public static void main (String[] args)
Note: try-catch statements identify a
{
block of statements that might cause
String code;
(throw) an exception.
char zone; int district, valid = 0, banned = 0;
Scanner scan – new Scanner (System.in);
The catch statement (follows the try)
System.out.print ("Enter product code (XXX to quit): ");
tells how a particular kind of exception
code = scan.nextLine();
is handled.
while (!code.equals ("XXX"))
catch statements called exception handlers
{
Can have multiple catch clauses.
try
{
zone = code.charAt(9);
district = Integer.parseInt(code.substring(3, 7));
If no problem in try, control resumes after
valid++;
last catch clause..
if (zone == 'R' && district > 2000)
banned++;
If an exception occurs and there is an
} // end try
appropriate exception handler for the
catch (StringIndexOutOfBoundsException exception)
exception class corresponding to the error.
{
System.out.println ("Improper code length: " + code);
} // end catch
Control resumes following last catch clause.
catch (NumberFormatException exception)
{
StringIndexOutOFBounds can be thrown by
System.out.println ("District is not numeric: " + code);
charAt() or substring() methods.
} // end catch
NumberFormatException can be thrown by
System.out.print ("Enter product code (XXX to quit): ");
the parseInt method, if substring does not
code = Keyboard.readString();
contain a valid integer.
} // end while
System.out.println ("# of valid codes entered: " + valid);
System.out.println ("# of banned codes entered: " + banned);
The finally Clause
A try statement can have an optional clause following the catch clauses,
designated by the reserved word finally
The statements in the finally clause always are executed
If no exception is generated, the statements in the finally clause are
executed after the statements in the try block complete
If an exception is generated, the statements in the finally clause are
executed after the statements in the appropriate catch clause complete
A finally clause is sometimes used to ensure certain code executes no
matter what… More later on this.
9/31
Exception Propagation
An exception can be handled at a higher level if it is not
appropriate to handle it where it occurs
Exceptions propagate up through the method-calling
hierarchy until they are caught and handled or until they
reach the level of the method
A try block that contains a call to a method in which an
exception is thrown can be used to catch that exception
See Propagation.java (page 546)
See ExceptionScope.java (page 547)
Let’s look at some code…
10/31
//************************************************************
// Propagation.java
Author: Lewis/Loftus
//
// Demonstrates exception propagation.
//************************************************************
public class Propagation
{
//----------------------------------------------------------------// Invokes the level1 method to begin the exception demonstration.
//----------------------------------------------------------------static public void main (String[] args)
{
ExceptionScope demo = new ExceptionScope();
// creates object of type demo.
System.out.println("Program beginning.");
demo.level1();
// invokes demo.level1()
System.out.println("Program ending.");
}// end main()
}// end Propagation class.
// ExceptionScope.java // Demonstrates exception propagation.
public class ExceptionScope
{ // Catches and handles the exception that is thrown in level3.
An exception can be caught within the method
public void level1()
where the exception occurs. (try clause is found
{
within a method; ditto for catch clauses.
System.out.println("Level 1 beginning.");
try
But, if a method calls another method and an
{
level2();
// transfers control to level2().
exception occurs there, that called method can
}// end try
handle the exception OR control can return to
catch (ArithmeticException problem)
the calling method that contains a try…catch
{
pair and be handled up there.
System.out.println ();
==========================================
System.out.println ("The exception message is: " + problem.getMessage());
Notice that we have
System.out.println ();
System.out.println ("The call stack trace:");
catch(ArithmeticException problem)
problem.printStackTrace();
An exception (recall) is an object and thus
System.out.println ();
problem is an object of type ArithmeticException.
}//end catch()
So, we can call:
System.out.println("Level 1 ending.");
problem.getMessage() and problem.printStaceTrace()
}// end level1()
// Serves as an intermediate level. The exception propagates through this method back to level1
public void level2()
{
System.out.println("Level 2 beginning.");
level3 ();
// transfers control to level 3().
System.out.println("Level 2 ending.");
}// end level 2()
// Performs a calculation to produce an exception. It is not caught and handled at this level.
public void level3 ()
{
int numerator = 10, denominator = 0;
// OK. Here’s the obvious error. Note: no exception handler in level 3()
System.out.println("Level 3 beginning.");
// To catch an exception at a higher level, the method with the exception
int result = numerator / denominator;
// must be invoked inside a try block that has a catch clause to handle exception.
System.out.println("Level 3 ending.");
// Control is passed up to level2(). But no handler here; control passes to level1()
} // end level3()
// Because level2() is invoked inside a try block that has a catch clause to handle
}// end class
// the exception, the exception is caught and handled now.
Program beginning
Level 1 beginning.
Level 2 beginning.
Level 3 beginning.
The exception message is: / by zero
The call stack trace:
java.lang.ArithmeticException: / by zero
at ExceptionScope.level3 (ExceptionScope.java:54)
at ExceptionScope.level2 (ExceptionScope.java.41)
at ExceptionScope.level1 (ExceptionScope.java:18)
Level1 ending
Program ending.
Note: control does not revert to the interrupted methods.!
The Exception Class Hierarchy
Important to note that all the classes that define the various exceptions are related by
inheritance. (p.549)
See
Object
note: Throwable is parent to both Error and Exceptin!
and many types of exceptions are derived from Exception class.
Throwable
Error
<Others>
Exception
RunTimeException
ArithmeticException
IndexOutOFBoundsException
NullPointerException
<Others>
There are many other child classes that define specific exceptions are part of other
packages. Inheritance relationships can span package boundaries.
14/31
The throw Statement
Because Throwable is a base class and Exception
inherits from it, a programmer can define his/her own
exceptions by extending the Exception class or one of
its descendants
Exceptions are ‘thrown’ using the throw statement
Usually a throw statement is nested inside an if
statement that evaluates the condition to see if the
exception should be thrown
Let’s see how we can create our own! We must derive
our own class.
See CreatingExceptions.java (page 550)
See OutOfRangeException.java (page 551)
15/31
//********************************************************************
// CreatingExceptions.java
Author: Lewis/Loftus
//
// Demonstrates the ability to define an exception via inheritance.
//********************************************************************
public class CreatingExceptions
{
// Creates an exception object and possibly throws it.
public static void main (String[] args) throws OutOfRangeException
{
// This is not part of the standard Java library!
final int MIN = 25, MAX = 40;
Scanner scan = new Scanner (System.in);
OutOfRangeException problem = // object is created (inheritance) and initialized.
new OutOfRangeException ("Input value is out of range.");
System.out.print ("Enter an integer value between " + MIN +
" and " + MAX + ", inclusive: ");
int value = scan.nextInt();
// Determines if the exception should be thrown
if (value < MIN || value > MAX)
throw problem;
System.out.println ("End of main method."); // may never reach
}// end main()
}// end CreatingEXceptions
//********************************************************************
// OutOfRangeException.java
Author: Lewis/Loftus
//
// Represents an exceptional condition in which a value is out of
// some particular range.
//********************************************************************
public class OutOfRangeException extends Exception
Here we are creating OUR OWN
{
Exception Handler (like ArrayIndexOutOfRange)
//----------------------------------------------------------------by extending the object, Exception.
// Sets up the exception object with a particular message.
//----------------------------------------------------------------OutOfRangeException (String message)
{
super (message);
} // end of OUtOFRangeException method()
}//end class OutOfRangeException
This is a simple example, but is very typical when we want to trap and process our own potential errors.
But it is important to note that this class is derived from Exception which is derived from Throwable..
Throwable provides the ability to use the throw statement!
There are other simple ways to accommodate an input error such as this. A simple if statement can check and
provide a message; alternatively, you may design your own Exceptions!
Checked Exceptions
An exception is either checked or unchecked
A checked exception either must be caught by a method,
or must be listed in the throws clause of any method that
may throw or propagate it
A throws clause is appended to the method header
We are saying that if a problem occurs, the method will
throw an exception.
The compiler will issue an error if a checked exception is
not handled appropriately
18/31
Unchecked Exceptions
An unchecked exception does not require explicit
handling, though it could be processed that way
The only unchecked exceptions in Java are objects of
type RuntimeException or any of its descendants
Errors are similar to RuntimeException and its
descendants

Errors should not be caught

Errors to not require a throws clause
19/31
Next three slides moved from last slides to here because
we have used these objects and methods.
They do deal with the various kinds of streams that
follow this discussion though…
20/31
The IOException Class
Operations performed by the I/O classes may throw an IOException

A file intended for reading or writing might not exist

Even if the file exists, a program may not be able to find it

The file might not contain the kind of data we expect
An IOException is a checked exception
In the next program, we create a file of test data from our program.
We use the FileWriter class to represent a text output file.
PrintWriter provides print and println methods to help FileWriter, which
has minimal method support for manipulating data.
21/31
// TestData.java // Demonstrates the use of a character file output stream.
import java.util.Random; import java.io.*;
public class TestData
{
// Creates a file of test data that consists of ten lines each containing ten integer values in range 10-99.
public static void main (String[] args) throws IOException
{
final int MAX = 10;
int value;
Random rand = new Random();
String file = "test.dat";
// creating a String object, file, that contains the name of the external file.
FileWriter fw = new FileWriter (file);
BufferedWriter bw = new BufferedWriter (fw);
PrintWriter outFile = new PrintWriter (bw); // PrintWriter contains methods print(), println(), close()…
// all these work together. Have added a layer in the file stream configuration to include a //BufferedWriter
object, bw. This simply gives the output stream buffering capabilities which makes the processing more efficient.
Buffering is always recommended in writing text files.
Note how the objects from one action are fed as input parameters to the next!!
for (int line=1; line <= MAX; line++)
{
for (int num=1; num <= MAX; num++)
{
value = rand.nextInt (90) + 10;
outFile.print (value + " ");
}// end inner for
outFile.println ();
// note we have not supplied an IOException handler. Thus, if anything goes
} // end outer for
// wrong, we will allow the program to terminate.
outFile.close();
// Because all IOExcpetions areh checked exceptions, we must include the
System.out.println ("Output file has been created: " + file); // throws clause on the method header to indicate
}// end main()
// that they may be thrown.
} // end class TestData
Text Files
Information can be read from and written to text files by
declaring and using the correct I/O streams
The FileReader class represents an input file
containing character data
The FileReader and BufferedReader classes
together create a convenient text file output stream just
as we used FileWriter, BufferedWriter, and PrintWriter in
the previous program.
23/31
I/O Streams and I/O Exceptions
A stream is a sequence of bytes that flow from a source to a destination
In a program, we read information from an input stream and write
information to an output stream
A program can manage multiple streams simultaneously
There are three streams considered standard I/O streams.



System class contains three object reference variables: in, out, err
that represent the three standard I/O streams. (public, static, so they
can be accessed through the System class)
Have used standard output stream with calls to System.out.println and
standard input stream when we used a Scanner object.
By default, they represent particular I/O devices: keyboard input,
monitor screen output. (These could be changed)
24/31
I/O Streams
The java.io package contains many classes that allow
us to define various other streams with particular
characteristics
Some classes assume that the data consists of
characters; other classes assume the data consists of
raw bytes of binary information.
Some classes allow us to manipulate the data in the
stream, such as buffering info or numbering it. By
judiciously combining classes, we can represent a
stream of information that has the characteristics we
wish.
This is a huge topic!!!
25/31
I/O Streams - Subdivisions
Data stream acts as either a source or destination
Processing stream - alters/manipulates basic data in the
stream
All kinds of opportunities for Input / Output Exceptions!!!
Input Streams
Output Streams
Data
Streams
Processing
Streams
Character
Streams
Byte
Streams
26/31
Character vs. Byte Streams
 A character stream manages 16-bit Unicode characters
A byte stream manages 8-bit bytes of raw binary data


A program must determine how to interpret and use the bytes
in a byte stream
Typically they are used to read and write sounds and images
The InputStream and OutputStream classes (and their
descendants) represent byte streams
 The Reader and Writer classes (and their
descendants) represent character streams
27/31
Data vs. Processing Streams
A data stream represents a particular source or destination such as a
string in memory or a file on disk
 A processing stream (also called a filtering stream) manipulates the
data in the stream

It may convert the data from one format to another

It may buffer the stream
 We have used data streams when we have read files and
processing streams, when we have buffered the input streams!
We must design our programs to be as resilient to these kinds of errors
as possible. They will occur! So we need to be able to handle them!
28/31