Date post: | 29-Dec-2015 |
Category: |
Documents |
Upload: | rafe-thornton |
View: | 215 times |
Download: | 2 times |
1 1
1 2
Chapter 14
Exception Handling
“If anything can go wrong, it will.”
1 3
• What is an “Exception”?
14.1 Introduction: definition of terms
exceptionexception An event during program
execution that prevents the program from continuing normally.
Generally, an error.
1 4
• Other languages react to errors by crashingcrashing.
• Java manages errors in a controlled way.
• Java permits recovery, if at all possible.
14.1 Introduction
1 5
• What users expect when an error happens:
14.1 Introduction: user expectations
—telltell them an error happened
—savesave all their work-in-progress, if possible.—allowallow them to exit the program gracefully.
1 6
• In Java, when an error happens, we say an exception has been thrown.
• Once an exception has been thrown, the JVM begins a searchbegins a search for some logic able to handle the exception.
14.1 Introduction: Overview of Java’s Approach
1 7
• The bit of logic able to handle the exception is called, naturally, an exception handlerexception handler.
• When the JVM finds the right exception handler,exception handler, we say the exception has been caught.
• Control is then transferred to the transferred to the ““catching blockcatching block.”
14.1 Introduction: Overview of Java’s Approach
1 8
• The exception can be thrown by the Java Virtual Machine—independent of the programmer’s control—or …
• the programmer herselfherself can throw the error, in response to some problem.
14.1 Introduction: Who Can Throw An Exception
1 9
• Understand, exception handling is really a kind of Control Flow, akin to the ‘if’ and ‘switch’ statements.
• The rationalerationale is this: you want to avoid cluttering up your program with logic to handle errors.
• So, you move the error-handling logic off to a separate place.
14.1 Introduction
1 10
i.) Program is executing.
ii.) Something goes wrong—i.e., zero division.
iii.) JVM creates an Exception object.
iv.) The Exception object contains information
about the exception that occurred.
v.) The Exception object is sent up the line until it encounters someone who can catch it.
14.1 Introduction: Error Handling Sequence
The possible "someones" who can handle the exception are the methods in the call stack above where the error occurred.
1 11
• Question:What is an Exception object?
• Answer:An instance of the class
Throwable.
• What makes something an instance of the class Throwable?• Answer:
Any class that extends the class Throwable, or whose Superclass extends that class.
14.1 Introduction: the Exception Object
1 12
• Objects that are instances of throwable—which means they subclass it (if an interface) or implement (if a class)—are eligible to be thrown by the JVM in response to an error.• After an exception, the JVM works backwards up the chain [stack] of method calls, until it encounters a “handler” for the exception—or a Superclass of the exception—whichever it encounters first.
14.1 Introduction: throwable
1 13
• This process of working back up the chain looking for a handler is described this way:
“Exceptions propagate error reporting
up the call stack of methods.”
14.1 Introduction: the call stack
1 14
• What constitutes a “handler” for a particular exception?
exception handler A block of code that reacts to a specific
type of exception. If the program can recover from the
exception, the program will resume executing after the exception handler has executed.
14.1 Introduction: definition
1 15
When To Use
Exception Handling
1 16
• Warning! Exception handling should only be used for exceptional situations.
Your program must try to prevent exceptionsprevent exceptions—with normal programming techniques—such as bounds checking on arrays or validation of input data.
Exception Handling is the last line of defense.
14.2 When to Use Exception Handling
1 17
The Classification
of
Exceptions
1 18
The Classification of Exceptions
• As we saw, an Exception is always an instance of the interface Throwable.
• You should try to prevent and catch all Exceptions, but there is a branch of the class Throwable that you should never attempt to catchnever attempt to catch:
instances of the class Error.
1 19
Throwable
These describe program or user mistakes. These
exceptions shouldshould be caught.
These describe internal errors and
resource exhaustion inside the JVM.
These should NOT be caught because they
are too major.
Our starting point, interface Throwable.
ErrorException
1 20
Throwable
ErrorException
IOIOException RuntimeRuntimeException
1 21
Throwable
ErrorException
IOIOException RuntimeRuntimeException
A RuntimeException happens because youyou made a programming
error.
Any other exception occurs because a bad thing beyond beyond your controlyour control (such
as an I/O error) happened to your otherwise good
program.
1 22
• Examples of RuntimeExceptions:—A bad cast.—An out-of-bounds array access.—Attempting to access a null reference
pointer.
• Examples of NonNon RuntimeExceptions: —Trying to read past the end of a file.
—Trying to open a malformed URL.
1 23
try,
throw and
catch
1 24
• Keywords
Java supports exception handling with these keywords:
try, throw and catch.
14.4 The Basics of Java Exception Handling
1 25
public class NoExceptionHandling{ public static void main( String[] args ) {
int x = 1, y = 0, z = 0;
z = x / y;
System.out.println( “x/y = “ + z ); }}
This will never print, nor will it tell you why it failed.
The program just dies.It has no exception
handling.
Division by zero.
1 26
public class HasExceptionHandling{ public static void main( String[] args ) {
int x = 1, y = 0, z = 0;
try{
z = x / y;System.out.println( “Not executed”);
}catch( Exception e ){
System.out.println( “Exception!”);}System.out.println( “x/y = “ + z );
}}
1 27
public class HasExceptionHandling{ public static void main( String[] args ) {
int x = 1, y = 0, z = 0;
try{
z = x / y;System.out.println( “Not executed”);
}catch( Exception e ){
System.out.println( “Exception!”);}System.out.println( “x/y = “ + z );
}}
Any code you think might throw an exception should be enclosed in a “try” block.
Every try block must be paired with at least one “catch” block—often more than one. The catch block will be executed onlyonly if an exception occurs.
When an exception happens, the remainder of the try block is abandoned. Variables go out of scope. No return is possible.
1 28
public class HasExceptionHandling{ public static void main( String[] args ) {
int x = 1, y = 0, z = 0;
try{
z = x / y;}catch( Exception e ){
System.out.println( “Exception!”);}System.out.println( “x/y = “ + z );
}}
The Sequence:i.) A particular exception occurs. ii.) The runtime system generates an exception object that matches the exception that occurred.iii.) Then, the runtime system goes looking for the nearest catch block that can handle that that specific type of specific type of exceptionexception.
If the nearest catch block doesn’t match the exception that happened, the runtime looks beyond this method for another catch block. But, in this case, Exception is the Superclass for all exceptions, so it always matches.
Exception!x/y = 0
1 29
public class HasExceptionHandlingWrongCatch{ public static void main( String[] args ) {
int x = 1, y = 0, z = 0;
try{
z = x / y;}catch( NullPointerException e ){
System.out.println( “Exception”);}System.out.println( “x/y = “ + z );
}}In thisthis case, however, the catch block is expecting a different type of exception. So, thisthis catch block doesn’t catch the error. The exception is NOT caught. The program crashes. The next statement after the catch block is not executed.
1 30
public class HasExceptionHandling{ public static void main( String[] args ) {
int x = 1, y = 0, z = 0;try{ z = x / y;}catch( NullPointerException npe ){ System.out.println( “Null Exception!”);}catch( DivideByZeroException dbze ){ System.out.println( “DivideByZeroException!” + dbze.toString() );}System.out.println( “Whoops!” );
}}
This one doesn’t match, so it is skipped.
This one doesdoes match, so it isis executed.
Since the exception was caught, execution can resume.
1 31
• Usually, many statements in your try block can cause exceptions and—since you can’t predict which one will pop—you place several different catch blocks after your one try block.
The most specific catch blocks should be listed firstfirst and the generic Exception (which is the Superclass to all exceptions) should be listed lastlast.
14.4 The Basics of Java Exception Handling
1 32
• This whole process is known as the: “Termination modelTermination model of exception handling.”
14.4 The Basics of Java Exception Handling: term
• The place where the exception occurred is the throw pointthrow point.
• After an exception has occurred, execution abandons the try blockabandons the try block from the throw point on.• We say the block that threw the exception expiresexpires.
1 33
The
finally
Block
1 34
The finally Block
• Java exception handling offers a third optionaloptional twist on the try-catch block:
• The finally block offers you a place to put code that must always be executed no matter whatno matter what—exception or no exception.• Remember: if you use a try, then you mustmust use a catch . • The finally is optionaloptional .
1 35
• The finally block is like the MafiaMafia—if you invite it in your code, it’s there whether you end up needing it or not.
• So, if your try block works perfectly—then the code in the finally block gets executed.
• And… if your try block throws an exception and the catch block catches the exception—then the code in the finally block stillstill gets executed.
The finally Block
1 36
public class HasFinallyBlockToo{ public static void main( String[] args ) {
int x = 1, y = 0, z = 0;
try{
z = x / y;}catch( NullPointerException e ){
System.out.println( “Exception”);}finally{
System.out.println( “Always!”);}
}}
Always, Always Always executes!
1 37
The try Block:A Net Over a Rabbit Hole
1 38
A Net Over a Rabbit Hole
• Obviously, a try block can catch an exceptionin the method where it’s located.
• But, a try block can alsoalso catch an exception far removedfar removed from the method where it’s located—as long as no other block in between catches it first.
1 39
public class GenericExceptionHandling{ public static void main( String[] args ) {
try{ // exception XYZ}catch( XYZ e ){ System.out.println( “XYZ Happened”);}
}}
This is routine exception handling,
which should now be familiar.
1 40
public class CatchesDistantException{ public static void main( String[] args ) {
try{ MyClass tom = new MyClass(); tom.causesException();}catch( XYZ e ){ System.out.println( “XYZ Happened”);}
}}As long as our catch block is the first one to be encountered, it will catch XYZ exception thrown deep inside of tom.causesException();
1 41
A Net Over a Rabbit Hole
• Now, we will see a more complex example of the previous example.
• We will show how a method call far down the method stack can:
—throw an exception and—propagate the exception back up
the callstack in search of a handler.
1 42
public class AException{ public AException() { System.out.println( "Cnst: AException" ); BException be = new BException(); }
public static void main(String[] args) { AException ae = new AException(); }}
public class BException{ public BException() { System.out.println( "Cnst: BException" ); CException ce = new CException(); try {
ce.populateArray(); } catch( ArrayIndexOutOfBoundsException e ) { //do something } }}
The pinkpink arrow will stay and wait, to illustrate that this method has not yet finished executing. It has opened another method in the call stack.
Now, the burgundyburgundy arrow will wait with the pink arrow, to show that now two methods are “stacked” up (in the stack) waiting for the execution of their methods to conclude.
AException.main()AException
Now, the redred arrow will stay and wait, to illustrate that this method has not yet finished executing. It has opened yet another method in the call stack.
BException
1 43
public class CException{ int[] intArray = new int[3];
public CException() { System.out.println( "Cnst: CException" ); }
public void populateArray() throws ArrayIndexOutOfBoundsException { intArray[0] = 100; intArray[1] = 101; intArray[2] = 102; intArray[3] = 103; }}
AException.main()AExceptionBException
These are the method calls from the other classes still waiting.
1 44
public class BException{ public BException() { System.out.println( "Cnst: BException" ); CException ce = new CException(); try {
ce.populateArray(); } catch( ArrayIndexOutOfBoundsException e ) { //do something } }}
public class AException{ public AException() { System.out.println( "Cnst: AException" ); BException be = new BException(); }
public static void main(String[] args) { AException ae = new AException(); }}
AException.main()AExceptionBException
Since the red Constructor method of CException finished, this line in the stack trace goes away.
Now, in the try block, we go back to the instance of class CException we just instantiated to execute its method populateArray()
1 45
public class CException{ int[] intArray = new int[3];
public CException() { System.out.println( "Cnst: CException" ); }
public void populateArray() throws ArrayIndexOutOfBoundsException { intArray[0] = 100; intArray[1] = 101; intArray[2] = 102; intArray[3] = 103; }}
AException.main()AException
These are the method calls from the other classes still waiting.
100 101 102
ArrayIndexOutOfBoundsException !
1 46
public class BException{ public BException() { System.out.println( "Cnst: BException" ); CException ce = new CException(); try {
ce.populateArray(); } catch( ArrayIndexOutOfBoundsException e ) { //do something } }}
public class AException{ public AException() { System.out.println( "Cnst: AException" ); BException be = new BException(); }
public static void main(String[] args) { AException ae = new AException(); }}
AException.main()AException
Since the try block threw an exception, when we propagate out of the called method, the JVM immediately looks for an appropriate catch block.
After the thrown exception has been successfully caught, the BException() constructor can finish.
1 47
public class AException{ public AException() { System.out.println( "Cnst: AException" ); BException be = new BException(); }
public static void main(String[] args) { AException ae = new AException(); }}
AException.main()
And lastly, the AException that started it all can finish and we’re back where we started.
s
Cnst: AExceptionCnst: BExceptionCnst: CExceptionException: ArrayIndexOutOfBoundsExceptionAfter method populateArray()
1 48
Advisory: although we used the RuntimeException ArrayIndexOutOfBoundsException for this
example, in fact this is one you should prevent through good old fashioned bounds checking, rather
than allowing it to throw an exception. Still, it makes for a good example.
1 49
Exception Handling: Limitations
1 50
• Exception-handling can only cope with synchronous errors—ones that occur in the execution step as it is currently being executed.
Exception Handling: Limitations
1 51
Exception Handling: Limitations
• Exception Handling is notnot able to cope with asynchronous errors—ones that only become apparent after a period of waiting, such as while waiting for a disk I/O read to happen.
1 52
Parsing the
Exception Object
1 53
Parsing the Exception Object
• In your catch block, it is customary to inspect and utilize the information about the exception contained in the Exception object.
1 54
…try{
//something bad happens here}catch( NullPointerException e ){
System.out.println( “NullPointerException” + e.toString() );
}
When the runtime system creates the exception object, the reference (here named ‘e’) contains everything that is
known about the exception. By using its toString() method, we reveal that
information.
1 55
Exception Handling
• Above all, Exception Handling is an opportunity to do something—it gives you the chance to intervene, but it is up to youyou to plan what happens when a specific exception is thrown.
1 56
…try{
//something bad happens here}catch( Exception e ){}
What have we done here?
Defeated The Exception Handling Mechanism! The
program will resume executing as if no
exception occurred!
1 57
Exception Handling
• In a console program—one that runs in the DOS window or UNIX shell—an unhandled exception results in the program terminating.
• A GUI program can go on executing even after an unhandled exception—but producing incorrect and unpredictable results in the process.
Moral of the Story?
In a GUI program—be especiallyespecially careful to handle your errors intelligently.
1 58
The Causes
of Exceptions
1 59
The Causes of Exceptions
• An Exception is Thrown for One of Three Reasons: 1.—An abnormal execution condition was synchronously detected by the Java Virtual Machine.
Possible Causes: —Evaluation of an expression violates the
rules of the Java Language, such as an integer divide by zero, etc. —An error occurs in loading or linking the Java program. —Some limitation in a resource is exceeded, such as using too much memory.
1 60
The Causes of Exceptions
• An Exception is Thrown for One of Three Reasons: 2.—A throw statement was executed in Java code
Possible Causes: —The program execution met an error that
had been expected.
1 61
The Causes of Exceptions
• An Exception is Thrown for One of Three Reasons: 3.—An asynchronous exception occurred.
Possible Causes: —The method stop() of class Thread was
invoked.—An internal error has occurred in the virtual machine.
1 62
How to re-re-throw Your Own Exceptions
1 63
How to re-re-throw Your Own Exceptions
• Usually, the JVM decides when to throw an exception.
• But, the programmer herself can choose when to throw an exception.
• Also, if your catch block handles an exception but then decides it really decides it really can’t handle itcan’t handle it, you can include logic in your catch block to re-throw the re-throw the exceptionexception to a handler higher up in the call stack.
1 64
try{
// Some processing here—no exception thoughtry{
// a DoodlebugException occurs here.}catch( DoodlebugException e ){
// some exception processing...System.out.println( “Doodlebug exception” );throw new BugException();
}}catch( BugException e ){
System.out.println( “BugException!” + e.toString() );
}
Firstly, we are within the blue try block.
After some ok processing, we’re in the red try block.
We’re able to do logic in the
catch block, but for some
reason, the programmer
thought it was necessary to rethrowrethrow the exception object ‘e’After the rethrow, the exception is
handled by the nearest enclosingenclosing catch block that is able to handle it.
1 65
How to re-re-throw Your Own Exceptions
• A method is not permitted to throw an exception of its own unless you specify in the method signature which specific Exceptions it throws.
1 66
Compile-Time Checking
of Exceptions
1 67
Compile-Time Checking of Exceptions
• If a method or constructor method announces that it has the ability to throw a certain type of exception, then the compiler checks to see if there are exception handlers in place to deal with those announced exceptions.The throws clause for the method must
mention the class of that exception, or one of the Superclasses of the exception that the method can throw.
1 68
Compile-Time Checking of Exceptions
• Exceptions that are explicitly announced as being possible by methods or constructors are known as...
“checked exceptions.”
1 69
Compile-Time Checking of Exceptions
• The other kinds of exceptions are known as
“unchecked exceptions.”These come from the class
RuntimeException and its subclasses, and from the class Error and its subclasses.
All other exception classes are checked exception classes.
1 70
Compile-Time Checking of Exceptions
• Why Errors are not checked:
Error and its subclasses are exempt from compile-time checking because they are unpredictable.
They can occur anywhere so it would needlessly clutter up your program if you attempted to catch them.
Also, more importantly, no recovery is ever possible from an Error .
1 71
Compile-Time Checking of Exceptions
• Why RuntimeExceptions are not checked:
These problems are usually beyond the programmer’s control. Thus, it would be a needless irritation to the programmer if she was forced to catch these.
1 72
public class TestException{ public static void main( String[] args ) {
int[] a = new int[2];a[0] = 1;a[1] = 2;a[3] = 3;System.out.println( “Array a[2]=” + a[2] );
}}
As you can see, this main method is ripe for an
exception. And, as expected, when we
execute it, we will see the following:
1 73
The JVM encountered an uncaught exception.
This was where the JVM was when it met the uncaught exception.
1 74
public static void main( String[] args ){ int[] a = new int[2]; try {
a[0] = 1;a[1] = 2;a[2] = 3;System.out.println( "Array a[2]=" + a[2] );
} catch( ArrayIndexOutOfBoundsException e ) {
System.out.println( "Do something here" + e ); }}
This is our array. It hastwo slots available.This statement will attempt
to use a non-existent 3rd slot in our array.
1 75
1 76
Clicking on the “e” exception object, we see exactly the kind that was thrown.
1 77
The Stack Dump:
When Your catch Misses
1 78
The Stack Dump
• If an unexpected exception occurs, then your carefully-planned catch block will fail to capture the exception.
• In this case, your console will fill with a stack dump:041.453 1024 HttpTransport X IO.Error java.net.SocketException: Connection reset by peer
java.lang.Throwable(java.lang.String)java.lang.Exception(java.lang.String)java.io.IOException(java.lang.String)java.net.SocketException(java.lang.String)void java.net.SocketOutputStream.socketWrite(byte [], int, int)void java.net.SocketOutputStream.write(byte [], int, int)void com.ibm.servlet.engine.http_transport.HttpTransportConnection.write(byte [], int, int)void com.ibm.servlet.engine.http_transport.HttpTransportConnection.prepareForWrite(int, java.lang.String, java.lang.String
[])void com.ibm.servlet.engine.srp.SRPConnection.prepareForWrite(int, java.lang.String, java.lang.String [], java.lang.String
[])void com.ibm.servlet.engine.srt.SRTServletResponse.commit()void com.ibm.servlet.engine.srt.SRTServletResponse.alertFirstWrite()void com.ibm.servlet.engine.srt.SRTOutputStream.write(byte [], int, int)void java.io.OutputStreamWriter.write(char [], int, int)void java.io.PrintWriter.write(char [], int, int)void com.ibm.servlet.engine.webapp.BufferedWriter.writeOut(char [], int, int)void com.ibm.servlet.engine.webapp.BufferedWriter.write(char [], int, int)void java.io.PrintWriter.write(char [], int, int)void com.sun.jsp.runtime.JspWriterImpl.flushBuffer()