exception handling

30
Exception Exception Handling Handling The finer details… The finer details…

Upload: bruce-nguyen

Post on 30-Dec-2015

25 views

Category:

Documents


3 download

DESCRIPTION

Exception Handling. The finer details …. The exceptions mechanism. When an exception is generated, control is immediately transferred to one of three places: catch block finally block the calling method. Understanding this “ goto ” behavior is important for several reasons: - PowerPoint PPT Presentation

TRANSCRIPT

Exception Exception HandlingHandlingThe finer details…The finer details…

The exceptions mechanismThe exceptions mechanism

• When an exception is generated, control is immediately

transferred to one of three places:

• catch block

• finally block

• the calling method

• Understanding this “goto” behavior is important for several

reasons:

• Maintaining objects’ state

• The code jumps from one place to another - logic gets

complicated.

The exceptions mechanismThe exceptions mechanism

• Consider the following example:

Class ExceptionTest {

public static void main(String[] args) {

ExceptionTest et = new ExceptionTest();

try {

Vector v = new Vector();

System.out.println(“calling m1()”);

et.m1();

System.out.println(“returning from call to m1()”);

}

catch (IOException e) {

System.out.println(“caught IOException in main()”);

}

} // End of main()

The exceptions mechanismThe exceptions mechanism

public void m1() throws IOException {

System.out.println(“entering m1()”);

try {

System.out.println(“calling m2()”);

m2();

System.out.println(“returning from call to m2()”);

System.out.println(“calling m3()”);

m3(true);

System.out.println(“returning from call to m2()”);

}

catch (IOException e) {

System.out.println(“caught IOException in m1()… rethrowing”);

throw e;

}

finally {

System.out.println(“in finally for m1()”);

}

} // End of m1()

The exceptions mechanismThe exceptions mechanism

public void m2() {

System.out.println(“entering m2()”);

try {

// perform some valid operation

}

catch (Exception e) {

System.out.println(“we will never get here”);

}

finally {

System.out.println(“in finally for m2()”);

}

} // End of m2()

The exceptions mechanismThe exceptions mechanism

public void m3(boolean generateException) throws IOException {

System.out.println(“entering m3()”);

try {

if (generateException)

throw new IOException();

}

finally {

System.out.println(“in finally for m3()”);

}

} // End of m3()

What will be the output of this program?

The exceptions mechanismThe exceptions mechanism

calling m1()

entering me1()

calling m2()

entering m2()

in finally for m2()

returning from call to m2()

calling m3()

entering m3() // We throw an exception here

in finally for m3()

caught IOException in m1()… rethrowing

in finally for m1()

caught IOException in main()

The exceptions mechanismThe exceptions mechanism

• A few notes about the flow of the program;

• If no exception is thrown, the catch block is never executed.

• If an exception is thrown, but no catch block exists, the

throw gets transferred to the calling method.

• A method that propagates an exception, must specify the

exception in the throws declaration.

• A finally block will always be executed, no matter what

happened in the try block.

• Because of the garbage collection, you don’t have to worry

about cleaning up objects memory.

Ignoring an exceptionIgnoring an exception

• When an exception is generated, what happens if you don’t

catch it?The thread on which the exception occurred will

terminate !!!• So, when an exception is generated, what can you do?

1) Catch the exception and handle it (it won’t propagate).

2) Catch the exception and rethrow it.

3) Catch the exception and throw a new one.

4) Do not catch it and let it propagate.

Options 2,3 and 4 require you to add the exception to the throws clause of your method.

• Option 1 stops the exception from propagating further.

• If you chose option 3, make sure the new exception contains

the relevant information from the original exception.

• Option 1 is often used in an ill-advised fashion to ignore the

exception:

Ignoring an exceptionIgnoring an exception

try {

// some code that generates an Exception

}

catch (Exception e) {

}

// code continues here

The exception was “eaten”

Ignoring an exceptionIgnoring an exception

• The danger here is that the code may fail later on.

• If you are not sure what to do with the exception in the early

stages of development, at minimum do something like the

following: try {

// some code that generates an Exception

}

catch (Exception e) {

System.out.println(e + “ was caught in method…”);

logReport(e);

}

// code continues here

Ignoring an exceptionIgnoring an exception

• Another useful approach is to use the printStackTrace method. try {

// some code that generates an Exception

}

catch (Exception e) {

System.out.println(e + “ was caught in method…”);

e.printStackTrace();

}

// code continues here

The best approach - do not put off the dirty work of exception and error handling.

Hiding an exceptionHiding an exception

• An exception is hidden when one is thrown from a catch or

finally block during the processing of a previously thrown

exception - option 3. try {

throw new Exception(“exception 1”);

}

catch (Exception e) {

throw new Exception(“exception 2”);

}

finally {

throw new Exception(“exception 3”);

}

Which exception is

thrown?

Hiding an exceptionHiding an exception

• A real life example:

try {

readFile();

}

catch (FileNotFoundException fne) {

// one way to handle the exception

}

catch (IOException ioe) {

// another way to handle it

}

Hiding an exceptionHiding an exception

public void readFile() throws FileNotFoundException, IOException {

BufferedReader br1, br2;

FileReader fr;

try {

fr = new FileReader(“data1.txt”); // FileNotFoundException

br1 = new BufferedReader(fr);

int i = br1.read(); // IOException

fr = new FileReader(“data2.txt”); // FileNotFoundException

br2 = new BufferedReader(fr);

int j = br2.read(); // IOException

}

finally {

if (br1 != null)

br1.close(); // IOException

if (br2 != null)

br2.close(); // IOException

}

}

A comprehensive throws clauseA comprehensive throws clause

• The throws clause is provided to alert callers of a method to the

checked exceptions it might generate.

• Consider the following example: class Exception1 extends Exception {}

class Exception2 extends Exception1 {}

class Exception3 extends Exception2 {}

class Lazy {

public void foo(int i) throws Exception1 {

if (i == 1)

throw new Exception1();

else if (i == 2)

throw new Exception2();

else if (i == 3)

throw new Exception3();

}

}

A comprehensive throws clauseA comprehensive throws clause

• Method foo() is declared to throw only one type of an exception

- Exception1.

• In reality, the method may throw one three exceptions.

• This code is perfectly legal as Exception2 and Exception3 are

derived from Exception1. This however has a drawback! try {

Lazy l = new Lazy();

l.foo(3);

}

catch (Exception1 e) {

// handle the exception

}

A comprehensive throws clauseA comprehensive throws clause

• If the user doesn’t have the source code, he will never know

about the other two exceptions.• When you write your functions, don’t be lazy

public void foo(int I) throws Exception1, Exception2, Exception3

Exceptions and overridingExceptions and overriding

• When you override a method, which exceptions types are you

allowed to throw, and which do you include in the throws clause?class Base {

public void foo() throws FileNotFoundException {

throw new FileNotFoundException();

}

}

Class Derived extends Base {

public void foo() throws IOException {

throw new IOException ();

}

}Compilation Error!!!

Exceptions and overridingExceptions and overriding

• When you override a method, the two methods must be

identical.

• What can you do in the overridden foo() method?

• Not throw any exception

• Throw a FileNotFoundException

• Throw an exception derived from FileNotFoundException

• When you override a method that does not throw an exception,

and add code to the overriding method that does, you must

catch that exception in the method.

• You are unable to propagate the exception outside the method.

Using finallyUsing finally

• The finally construct enables code to execute whether or not an

exception occurred.

• Using finally is a good practice to maintain the internal state of

object.

• Here is how you would write code without the use of finally:

Socket s = new Socket(“sol4”, 2783);

BufferedReader r = new BufferedReader(new InputStreamReader(s.getInputStream()));

try {

String text = r.readline();

}

catch (IOException e) {

s.close();

throw e;

}

s.close();

Using finallyUsing finally

• Using finally the code become more compact:

Socket s = new Socket(“sol4”, 2783);

BufferedReader r = new BufferedReader(new InputStreamReader(s.getInputStream()));

try {

String text = r.readline();

}

finally {

s.close();

}

Exiting the try blockExiting the try block

• The try/finally block is straightforward but has some behavior

that catches even the knowledgeable programmer off guard.

• There is no way to exit the try block without executing its finally

block. If the finally block exists, it always executes.*

• Code leaves a try block when any of the following occurs:

• An exception is thrown.

• The try block finishes normally.

• A return, break or continue statement is executed within it.

*You can always use System.exit(0), but on the other hand, unplugging

the computer during the try block will not execute it either.

Exceptions and performanceExceptions and performance

• Exceptions can have negative impact on the performance of your

code.

• Structuring your code correctly, can greater improve performance.

• There are two areas of exceptions that affect performance:

• The effect of throwing an exception.

• The effect of try/catch blocks in your code.• The act of throwing an exception is not free - Exceptions are

objects, and thus need to be created - throw new Exception().

• Creating objects takes time, so only throw exceptions when you

have to.

Exceptions and performanceExceptions and performance

• Placing exceptions inside loops can slow down the execution of

code as the following illustrates:

Public void m1(int size) {

int[] array = new int[size];

try {

for (int i=0; i<size; i++)

array[i] = i;

}

catch (Exception) {} // exception ignore on purpose.

}

Public void m2(int size) {

int[] array = new int[size];

for (int i=0; i<size; i++) {

try {

array[i] = i;

}

catch (Exception) {} // exception ignore on purpose.

}

}

Exceptions and performanceExceptions and performance

• m2 is approximately 20% slower than m1.

• The bytecode for m2 has more opcode executed in its loop.

Exceptions in constructorsExceptions in constructors

• Traditional error reporting from constructors can be problematic

because a constructor has no return value.

• Error reporting from constructors have typically been

accomplished via several techniques:

• Two stage construction.

• An internal flag.• These techniques lack in robustness – they rely on the user of the

class to remember to perform the two stage construction or to

check an internal flag.

• You avoid all this by throwing exceptions from your constructors.

Exceptions & Objects statesExceptions & Objects states

• Throwing an exception is easy.

• The hard part is to minimize the damage you cause by throwing it.• What is the purpose of throwing an exception ?

• Explicitly - to inform another part of the system about a

problem.

• Implicitly - to allow the system to potentially recover from the

problem and continue running smoothly. • Objects whose state was altered prior to the exception could be

referenced after the exception.

• What good is it to throw an exception if you leave objects in invalid

or undefined state?

Exceptions & Objects statesExceptions & Objects states

class MyList {}

class Foo {

private int numElements;

private MyList list;

public void add(Object o) throws Exception {

// …

numElements++;

if (list.maxElements() < numElements) {

// Reallocate list and copy elements - could throw an exception

}

list.addToList(o); // could throw an exception

}

}

Exception Exception HandlingHandling-- The End ---- The End --