View
305
Download
2
Tags:
Embed Size (px)
DESCRIPTION
Citation preview
LIS4930 © PIC
FinallyThere are times when you want some code to run regardless of an exception – you want it to run no matter what!
The finally block is where you put code that must run regardless of an exception.
A finally block lets you put all your important cleanup code in one place instead of duplicating it like this:
try {turnOvenOn( );x.bake( );turnOvenOff( );
} catch(BakingException ex) {
ex.printStackTrace();turnOvenOff( );
}
try {turnOvenOn( );x.bake( );
} catch(BakingException ex) {
ex.printStackTrace();} finally {
turnOvenOff( );}
LIS4930 © PIC
A Method Can Throw More Than One Exception
public class Laundry {public void doLaundry( ) throws PantsException, ShoeException {
// code that could throw either exception}
}
public class Foo {public void go( ) {
Laundry laundry = new Laundry( );try {
laundry.doLaundry( );} catch(PantsException ex) {
// recovery code} catch(ShoeException ex) {
// recovery code}
}}
LIS4930 © PIC
Exceptions Are Polymorphic
Don’t forget Exceptions are objects so a ClothingException can be extended into ShirtExceptions, PantsExceptions, and DressExceptions. Therefore:
You can DECLARE exceptions using a supertype of the exceptions you throw.
1
You can CATCH exceptions using a supertype of the exception thrown.
2
Look at page 330 for an example of polymorphic exceptions
Just because you CAN catch everything with one big super polymorphic catch, doesn’t mean you SHOULD.
Write a different catch block for each exception that you need to handle uniquely.
LIS4930 © PIC
Catching Multiple Exceptions
Multiple catch blocks must be ordered from smallest to biggest.
You can’t put bigger baskets above smaller baskets.
try {laundry.doLaundry( )
} catch (ClothingException ce) {
// recovery code goes here} catch (ShoeException se ) {
// recovery code goes here} catch (DressException de) {
// recovery code goes here}
Don’t do this!
LIS4930 © PIC
Paying It Forward
If you don’t want to handle an exception you can just throw it yourself so that whomever calls YOU will have to handle the exception.
If you call a risky method that does throw an exception, instead of you handling it, you can keep throwing it.
public void foo( ) throws PantsException, ShoeException {
// call risky method without a try/catch blocklaundry.doLaundry( );
}
LIS4930 © PIC
Ducking (by paying it forward) Only Delays the Inevitable
doLaundry( ) throws a ClothingException1
foo( ) ducks the exception2
main( ) ducks the exception3
The JVM shuts down4
public class Washer {Laundry laundry = new Laundry( );public void foo( ) throws ClothingException {
laundry.doLaundry( );}
public static void main(String[] args) throws ClothingException {Washer a = new Washer( );a.foo( );
}}
LIS4930 © PIC
Handle or Declare!So now we’ve seen both ways to satisfy the compiler when you call a risky (exception-throwing) method.
HANDLE – Wrap the risky call in a try/catch block1
DECLARE – duck it / pay it forward2
Let’s look at the sequencer to see how each method works.
LIS4930 © PIC
Exception Rules
You cannot have a catch or finally without a try
1
You cannot put code between the try and the catch
2
A try MUST be followed by either a catch or a finally
3
A try with only a finally (no catch) must still declare the exception
4
void go ( ) {Foo f = new
Foo( );f.foof( );
catch(fooException ex) { }}
try {x.doStuff( );
} finally {// cleanup
}
try {x.doStuff( );
} int y = 43;} catch (Exception ex ) { }
void go ( ) throws FooException {
try {x.doStuff(
);} finally { }
}
LIS4930 © PIC
Familiar Example
We now know what this means.
But, what about this?
LIS4930 © PIC
Input and Output
The java.io package includes a rich collection of different classes to support I/O.
Different classes provide different ways for programs to organize and retrieve data.
Java programs do not communicate directly with external devices, instead they create a stream object to connect the program to the device. Each stream functions as a conduit that establishes a path for the data to flow between the program and the I/O device.
LIS4930 © PIC
Streams
Java supports several different streams for different purposes.
Executing
Program
Output Stream
File (on disk)
Executing
ProgramInput Stream
File (on disk)
LIS4930 © PIC
Stream HierarchyOutput Stream
(abstract)
FileOutputStream
ObjectOutputStream
FilterOutputStream
DataOutputStream
to write raw bytes
to write whole objects
to write primitive values
Input Stream (abstract)
FileInputStream
ObjectInputStream
FilterInputStream
DataInputStream
to read raw bytes
to read whole objects
to read primitive values
LIS4930 © PIC
Using Streams
1. Open the file for input, instantiating associated stream objects.
2. Call read methods to retrieve part of or the entire stream’s content.
3. Close the file/stream.
1. Open the file for output, instantiating associated stream objects.
2. Call read methods to write data into the stream.
3. Close the file/stream.
Input Streams
Output Streams
LIS4930 © PIC
DataInputStreams & DataOutputStreams
FileOutputStream
Executing Program
DataOutputStream
File (on disk)
FileInputStream
Executing Program
DataInputStream
File (on disk)
LIS4930 © PIC
Text Files
Input StreamExecuting Program
Reader
File (on disk)
Input StreamExecuting Program
Reader
File (on disk)
BufferedRea
der
Output StreamExecuting Program
Writer
File (on disk)
BufferedWri
ter
Output StreamExecuting Program
Writer
File (on disk)
LIS4930 © PIC
Familiar Example
What if we didn’t “duck” the exceptions?
Now we know what this means
LIS4930 © PIC
Input and Output of Files
Use a FileReader/FileWriter objects as your “Reader” conduit.
Input StreamExecuting Program
FileReader
File (on disk)
Input StreamExecuting Program
FileReader
File (on disk)
BufferedRea
der
Output StreamExecuting Program
FileWriter
File (on disk)
BufferedWri
ter