Download presentation
Presentation is loading. Please wait.
Published byBrook Hunter Modified over 9 years ago
1
1 1. Normal and exceptional control flow 2. Java exception types 3. Exception handling syntax 4. Inheritance
2
2 public void h() { return; } What is an exception ? = problem that can NOT be solved IN THE CURRENT CONTEXT public void f() { g(); return; } public void g() { h(); return; } Problem Normal execution path
3
3 public void h() { return; } Solution without exceptions public void f() { g(); return; } public void g() { h(); return; } Dangerous code if(!errorCondition) { } else return errorCode; int if(h()==errorCode) return errorCode; int if(g()==errorCode) { } Error handling code Normal execution path Exceptional execution path
4
4 public void h() { return; } Solution with exceptions public void f() { return; } Dangerous code try { g(); } catch(Exception e) { } Error handling code Normal execution path Exceptional execution path if(!errorCondition) { } else throw new Exception(); throws Exception public void g() { h(); return; } throws Exception
5
5 Exception mechanisms terminationresumption Is it useful to to return to exception creation context after exception handling ? YESNO Dangerous Code Calling context Exception Handler Terminates caller Dangerous Code Calling context Exception Handler Resumes caller Java, C++ approach
6
6 Exception misuse public class ExceptionAbuse { public static void main(String[] args) { int[] a={1,2,3,4}; printArray(a); } static void printArray(int[] a) { try { int i=0; while(true) { System.out.print(" "+a[i]); i++; } } catch(Exception e) { System.out.println("\nEnd of array."); } Problem can be solved in current context (even current scope) ! DO NOT USE EXCEPTIONS IN THESE CASES, SOLVE THE PROBLEM !
7
7 Exception hierarchy By default : checked exceptions UNchecked exceptions
8
8 Try - catch Basic exception syntax try { } catch(Exception e) { } Guarded code block Can raise Exceptions Exception Handler Contains throw-statements explicitly through method call (declaring so) Operation1; Operation2;
9
9 Checked Exceptions import java.io.*; class ExceptionSyntax { public static void main(String[] args) { try { System.out.println("Entering try block"); openFile("keywords.txt"); System.out.println("After 1st open"); openFile("others.txt"); System.out.println("After 2nd open"); System.out.println("Closing try block"); } catch(FileNotFoundException e) { System.err.println("Entering exception handler."); System.err.println("Nonexisting keywords file."); } public static void openFile(String s) throws FileNotFoundException { System.out.println("Inside openFile()"); if(s.equals("keywords.txt")) { }// do something useful here else throw new FileNotFoundException(); } Entering try block Inside openFile() After 1st open Inside openFile() Entering exception handler. Nonexisting keywords file. Error output : Not redirected
10
10 Unchecked Exceptions import java.io.*; class UncheckedExceptionSyntax { public static void main(String[] args) { int[] a={1,2,3,4,5}; System.out.println("Entering try block"); giveElement(a,3); System.out.println("After 1st giveElement()"); giveElement(a,0); System.out.println("After 2nd giveElement()"); giveElement(a,10); System.out.println("After 3rd giveElement()"); System.out.println("Closing try block"); System.out.println("After try."); } public static int giveElement(int[] a,int i) { System.out.println("Inside giveElement()"); return a[i]; } Entering try block Inside giveElement() After 1st giveElement() Inside giveElement() After 2nd giveElement() Inside giveElement() Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 10 at UncheckedExceptionSyntax.giveElement(UncheckedExceptionSyntax.ja ) at UncheckedExceptionSyntax.main(UncheckedExceptionSyntax.java:11)
11
11 Unchecked Exceptions import java.io.*; class UncheckedExceptionSyntax { public static void main(String[] args) { int[] a={1,2,3,4,5}; try { System.out.println("Entering try block"); giveElement(a,3); System.out.println("After 1st giveElement()"); giveElement(a,0); System.out.println("After 2nd giveElement()"); giveElement(a,10); System.out.println("After 3rd giveElement()"); System.out.println("Closing try block"); } catch(ArrayIndexOutOfBoundsException e) { System.err.println("Inside Exception handler."); System.err.println("Array index error !"); } System.out.println("After try."); } public static int giveElement(int[] a,int i) { System.out.println("Inside giveElement()"); return a[i]; } Entering try block Inside giveElement() After 1st giveElement() Inside giveElement() After 2nd giveElement() Inside giveElement() Inside Exception handler. Array index error ! After try.
12
12 Unchecked Exceptions import java.io.*; class UncheckedExceptionSyntax { public static void main(String[] args) { int[] a={1,2,3,4,5}; try { System.out.println("Entering try block"); giveElement(a,3); System.out.println("After 1st giveElement()"); giveElement(a,0); System.out.println("After 2nd giveElement()"); giveElement(a,10); System.out.println("After 3rd giveElement()"); System.out.println("Closing try block"); } catch(ArrayIndexOutOfBoundsException e) { System.err.println("Inside Exception handler."); System.err.println("Array index error !"); } System.out.println("After try."); } public static int giveElement(int[] a,int i) { System.out.println("Inside giveElement()"); if(i<1) throw new ArrayIndexOutOfBoundsException(); return a[i]; } Entering try block Inside giveElement() After 1st giveElement() Inside giveElement() Inside Exception handler. Array index error ! After try.
13
13 Own Exceptions class OwnException extends Exception {}; class OwnExceptionTest { public static void main(String[] args) { int[] a={1,2,3,4,5}; try { System.out.println("Entering try block"); giveElement(a,3); System.out.println("After 1st giveElement()"); giveElement(a,0); System.out.println("After 2nd giveElement()"); System.out.println("Closing try block"); } catch(OwnException e) { System.err.println("Inside Exception handler."); System.err.println("Can not handle even array indices"); } System.out.println(“After try.”); } public static int giveElement(int[] a,int i) throws OwnException { // can not handle even indices System.out.println("Inside giveElement()"); if(i%2==0) throw new OwnException(); return a[i]; } Entering try block Inside giveElement() After 1st giveElement() Inside giveElement() Inside Exception handler Can not handle even array indices After try.
14
14 Own RuntimeExceptions class OwnRuntimeException extends RuntimeException { public String toString() { return "Can not handle even array indices"; } }; class OwnExceptionTest { public static void main(String[] args) { int[] a={1,2,3,4,5}; System.out.println("Entering try block"); giveElement(a,3); System.out.println("After 1st giveElement()"); giveElement(a,0); System.out.println("After 2nd giveElement()"); System.out.println("Closing try block"); System.out.println("After try."); } public static int giveElement(int[] a,int i) { // can not handle even indices System.out.println("Inside giveElement()"); if(i%2==0) throw new OwnRuntimeException(); return a[i]; } Entering try block Inside giveElement() After 1st giveElement() Inside giveElement() Exception in thread "main" Can not handle even array indices at OwnExceptionTest.giveElement(OwnRuntimeException.java:22) at OwnExceptionTest.main(OwnRuntimeException.java:14)
15
15 Multiple catches class ExceptionA extends Exception { public ExceptionA() {} }; class ExceptionB extends Exception{ public ExceptionB() {super("Uneven argument !");} }; class MultCatch { public static void main(String[] args) { try { if(Math.random()>0.5) f(3); else g(5); } catch(ExceptionA e) { System.out.println(e); } catch(ExceptionB e) { System.out.println(e); } public static void f(int i) throws ExceptionA { if(i%2==1) throw new ExceptionA(); } public static void g(int i) throws ExceptionB { if(i%2==1) throw new ExceptionB(); } Handler for ExceptionA Hanlder for ExceptionB
16
16 Catching … class ExceptionA extends Exception {}; class ExceptionB extends ExceptionA {}; class HierCatch { public static void main(String[] args) { try { if(Math.random()>0.5) f(3); else g(5); } catch(ExceptionA e) { System.out.println(e); } public static void f(int i) throws ExceptionA { if(i%2==1) throw new ExceptionA(); } public static void g(int i) throws ExceptionB { if(i%2==1) throw new ExceptionB(); } Handler for ALL ExceptionA
17
17 Catch what ? Main information : the TYPE of the exception (class name normally hints at the cause of the exception) Throwable Get exception description String getMessage() String getLocalizedMessage() String toString() Get/set (!) stack information void printStackTrace(); void printStackTrace(PrintStream) void printStackTrace(PrintWriter) Throwable fillInStackStrace() void setStackTrace(StackTraceElement[]) Get/set exception cause void initCause(Throwable) Throwable getCause()
18
18 Tracing stacks class OwnException extends Exception { public OwnException() {super("-> A new Exception <-");} }; class OwnExceptionStack { public static void main(String[] args) { int[] a={1,2,3,4,5}; try { giveElement(a,0); System.out.println("Closing try block"); } catch(OwnException e) { System.err.println("Can not handle even array indices"); System.out.println(e); System.out.println(e.getMessage()); e.printStackTrace(); } System.out.println("After try."); } public static int giveElement(int[] a,int i) throws OwnException { System.out.println("Inside giveElement()"); f(i); return a[i]; } public static void f(int i) throws OwnException { System.out.println("Inside f()"); if(i%2==0) throw new OwnException(); } Inside giveElement() Inside f() Inside Exception handler. OwnException: -> A new Exception <- -> A new Exception <- OwnException: -> A new Exception <- at OwnExceptionStack.f(OwnExceptionStack.java:31) at OwnExceptionStack.giveElement(OwnExceptionStack.java:26) at OwnExceptionStack.main(OwnExceptionStack.java:12) After try.
19
19 Rethrowing = (partly) handle the exception and throw the SAME Exception Object again With rethrowing class Rethrow { public static void main(String[] args) { int[] a={1,2,3,4,5}; try { f(a,0); System.out.println("Closing try block"); } catch(OwnException e) { System.out.println("main : Exception handler"); e.printStackTrace(); } System.out.println("After try."); } public static int f(int[] a,int i) throws OwnException { try { g(i); } catch(OwnException e) { System.out.println("f : Exception handler"); e.printStackTrace(); throw e; } return a[i]; } public static void g(int i) throws OwnException { if(i%2==0) throw new OwnException(); } f : Exception handler OwnException at Rethrow.g(Rethrow.java:26) at Rethrow.f(Rethrow.java:17) at Rethrow.main(Rethrow.java:8) main : Exception handler OwnException at Rethrow.g(Rethrow.java:26) at Rethrow.f(Rethrow.java:17) at Rethrow.main(Rethrow.java:8) After try.
20
20 Rethrowing Without rethrowing class NoRethrow { public static void main(String[] args) { int[] a={1,2,3,4,5}; try { f(a,0); System.out.println("Closing try block"); } catch(OwnException e) { System.out.println("main : Exception handler"); e.printStackTrace(); } System.out.println("After try."); } public static int f(int[] a,int i) throws OwnException { try { g(i); } catch(OwnException e) { System.out.println("f : Exception handler"); e.printStackTrace(); throw new OwnException(); } return a[i]; } public static void g(int i) throws OwnException { if(i%2==0) throw new OwnException(); } f : Exception handler OwnException at Rethrow.g(Rethrow.java:26) at Rethrow.f(Rethrow.java:17) at Rethrow.main(Rethrow.java:8) main : Exception handler OwnException at Rethrow.f(Rethrow.java:21) at Rethrow.main(Rethrow.java:8) After try.
21
21 Rethrowing With rethrowing & changing the stack trace class Rethrow { public static void main(String[] args) { int[] a={1,2,3,4,5}; try { f(a,0); System.out.println("Closing try block"); } catch(OwnException e) { System.out.println("main : Exception handler"); e.printStackTrace(); } System.out.println("After try."); } public static int f(int[] a,int i) throws OwnException { try { g(i); } catch(OwnException e) { System.out.println("f : Exception handler"); e.printStackTrace(); e.fillInStackTrace(); throw e; } return a[i]; } public static void g(int i) throws OwnException { if(i%2==0) throw new OwnException(); } f : Exception handler OwnException at Rethrow.g(Rethrow.java:27) at Rethrow.f(Rethrow.java:17) at Rethrow.main(Rethrow.java:8) main : Exception handler OwnException at Rethrow.f(Rethrow.java:21) at Rethrow.main(Rethrow.java:8) After try. no new Exception object hide underlying structure
22
22 Exception causes GOAL : Decoupling layers WITHOUT loosing information throwing exceptions introduces type dependencies between software layers hide lower layers (to reduce dependencies) classical solution : catch exception and throw known exception to upper layer Problem Unknown Exception Solution Known Exception ExceptionA ExceptionB throw new ExceptionB() ExceptionB e= new ExceptionB(); e.initCause(excepA); throw e; Cause of ExceptionB
23
23 Exception causes class ExceptionA extends Exception {}; class ExceptionB extends Exception {}; class Causes { public static void main(String[] args) { int[] a={1,2,3,4,5}; try { f(a,0); System.out.println("Closing try block"); } catch(ExceptionB e) { System.out.println("main : Exception handler"); e.printStackTrace(); System.out.println("Cause : "); (e.getCause()).printStackTrace(); } System.out.println("After try."); } public static int f(int[] a,int i) throws ExceptionB { try { g(i); } catch(ExceptionA eA) { ExceptionB eB= new ExceptionB(); eB.initCause(eA); throw eB; } return a[i]; } public static void g(int i) throws ExceptionA { if(i%2==0) throw new ExceptionA(); } main : Exception handler ExceptionB at Causes.f(Causes.java:22) at Causes.main(Causes.java:9) Caused by: ExceptionA at Causes.g(Causes.java:29) at Causes.f(Causes.java:20)... 1 more Cause : ExceptionA at Causes.g(Causes.java:29) at Causes.f(Causes.java:20) at Causes.main(Causes.java:9) After try.
24
24 Nesting try class ExceptionA extends Exception {}; class ExceptionB extends Exception {}; class Nesting { public static void main(String[] args) { try { f(1);//f(0); f(0);//f(1); } catch(ExceptionB eB) { System.out.print("B"); } System.out.print("C"); } catch(ExceptionA eA) { System.out.print("A"); } public static void f(int i) throws ExceptionA,ExceptionB { if(i%2==0) throw new ExceptionA(); else throw new ExceptionB(); }
25
25 The finally clause try { } catch( …) { … } catch( … ) { … } finally { … } Guaranteed execution used for clean-up code not necessary in C++ (destructor cleans up !)
26
26 Finally : illustration import java.io.*; class ExceptionA extends Exception {}; class ExceptionB extends Exception {}; class FinallyDemo { public static void main(String[] args) { for(int i=2;i>=0;i--) { try { System.out.println("Inside try."); f(i); } catch(ExceptionA eA) { System.out.println("ExceptionA handler"); continue; } finally { System.out.println("Inside finally."); } System.out.println("Statement in for-loop."); } public static void f(int i) throws ExceptionA { if(i%2==0) throw new ExceptionA(); } Inside try. ExceptionA handler Inside finally. Statement in for-loop. Inside try. Inside finally. Statement in for-loop. Inside try. ExceptionA handler Inside finally. Statement in for-loop. Without continueWith continue Inside try. ExceptionA handler Inside finally. Inside try. Inside finally. Statement in for-loop. Inside try. ExceptionA handler Inside finally.
27
27 Why finally ? class FinallyDemo2 { public static void main(String[] args) { for(int i=0;i<3;i++) { try { f(i); } catch(ExceptionA eA) { System.out.println("ExceptionA handler"); } public static void f(int i) throws ExceptionA { try { if(g(i)) throw new ExceptionA(); } catch (ExceptionB eB) { System.out.println("ExceptionB handler"); } finally { System.out.println(“”+i+“: Cleaning up !"); } public static boolean g(int i) throws ExceptionB { if(i%3==0) throw new ExceptionB(); else return (i%3==1); } ExceptionB handler 0 : Cleaning up ! 1 : Cleaning up ! ExceptionA handler 2 : Cleaning up ! Cope with Exceptions if Guaranteed execution is requried (iteration i=1);
28
28 Inheritance : Exception rules Methods can only raise exceptions declared in the base class class ExceptionA extends Exception {} class ExceptionB extends Exception {} class A { public void f() {} public void g() throws ExceptionA {} public void h() throws Exception {} } class B extends A{ public void f() {} // OK public void f() throws ExceptionA {} public void f() throws Exception {} public void g() {} //OK public void g() throws ExceptionA {} //OK public void g() throws ExceptionB {} public void g() throws Exception {} public void h() {} //OK public void h() throws ExceptionA {} //OK public void h() throws ExceptionB {} //OK public void h() throws Exception {} //OK } WHY ? Checked Exceptions enforced AT COMPILE time (statically) Liskov’s Substitution Principle Often base class methods declare “throws Exception” to allow Subclasses to throw !
29
29 Inheritance : Exception rules EXCEPTION RESTRICTION RULE DOES NOT APPLY TO CONSTRUCTORS WHY ? Constructors are NOT inherited NO polymorphism for constructors NO LSP-violation Standard rules apply : declare to throw Exceptions caused BEWARE : implicit constructor calls ! class A { public A() {} } class B extends A{ public B() throws ExceptionA {} } class A { public A() throws ExceptionA{} } class B extends A{ public B() {} }
30
30 Inheritance rules class ExceptionA extends Exception {} class ExceptionB extends Exception {} class A { public A() throws ExceptionA{} public A(int i) throws ExceptionB {} } class B extends A{ //public B() throws ExceptionA {} //public B() throws ExceptionA {super(1);} //public B() throws ExceptionB {} //public B() throws ExceptionB {super(1);} //public B() throws ExceptionA,ExceptionB {} //public B() throws ExceptionA,ExceptionB {super(0);} //public B() throws Exception{} }
Similar presentations
© 2025 SlidePlayer.com. Inc.
All rights reserved.