1 / 30

Exception Handling

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:

Download Presentation

Exception Handling

An Image/Link below is provided (as is) to download presentation Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author. Content is provided to you AS IS for your information and personal use only. Download presentation by click this link. While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server. During download, if you can't get a presentation, the file might be deleted by the publisher.

E N D

Presentation Transcript


  1. Exception Handling The finer details…

  2. 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: • Maintaining objects’ state • The code jumps from one place to another - logic gets • complicated.

  3. The 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()

  4. The 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()

  5. The 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()

  6. The 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?

  7. The 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()

  8. The 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.

  9. Ignoring 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.

  10. Ignoring an exception • 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: try { // some code that generates an Exception } catch (Exception e) { } // code continues here The exception was “eaten”

  11. Ignoring 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

  12. Ignoring 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.

  13. Which exception is thrown? Hiding 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) { thrownewException(“exception 2”); } finally { thrownewException(“exception 3”); }

  14. Hiding 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 }

  15. Hiding 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 } }

  16. A 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(); } }

  17. A 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 }

  18. A 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

  19. Exceptions 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!!!

  20. Exceptions 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.

  21. Using 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();

  22. Using 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(); }

  23. Exiting 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.

  24. Exceptions 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.

  25. Exceptions 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. • }

  26. Exceptions and performance 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. } } • m2 is approximately 20% slower than m1. • The bytecode for m2 has more opcode executed in its loop.

  27. Exceptions 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.

  28. Exceptions & 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?

  29. Exceptions & 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 } }

  30. Exception Handling -- The End --

More Related