Post on 29-Jan-2016
1
1. Normal and exceptional control flow2. Java exception types3. Exception handling syntax4. Inheritance
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
public void h() {
return;}
Solution without exceptions
public void f() {
g();
return;}
public void g() {
h();
return;}
Dangerous code
if(!errorCondition) {
} else return errorCode;
intif(h()==errorCode)
return errorCode;
intif(g()==errorCode) {
}
Error handlingcode
Normal execution path
Exceptional execution path
4
public void h() {
return;
}
Solution with exceptions
public void f() {
return;}
Dangerous code
try {
g();
} catch(Exception e) {
}
Error handlingcode
Normal execution pathExceptional execution path
if(!errorCondition) {
} else throw new Exception();
throws Exception
public void g() {
h();
return;}
throws Exception
5
Exception mechanisms
termination resumption
Is it useful to to return to exception creation context after exception handling ?
YESNO
Dangerous Code
Calling context
ExceptionHandler
Terminates caller
Dangerous Code
Calling context
ExceptionHandler
Resumes caller
Java, C++ approach
6
Exception misusepublic 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
Exception hierarchy
By default : checked exceptions
UNchecked exceptions
8
Try - catchBasic exception syntax
try {
} catch(Exception e) {
}
Guarded code blockCan raise Exceptions
Exception Handler
Contains throw-statements• explicitly• through method call (declaring so)
Operation1;
Operation2;
9
Checked Exceptionsimport 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
Unchecked Exceptionsimport 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
Unchecked Exceptionsimport 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
Unchecked Exceptionsimport 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
Own Exceptionsclass 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
Own RuntimeExceptionsclass 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
Multiple catchesclass 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
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
Catch what ?
Main information : the TYPE of the exception(class name normally hints at the cause of the exception)
Throwable Get exception descriptionString getMessage()String getLocalizedMessage()String toString()
Get/set (!) stack informationvoid printStackTrace();void printStackTrace(PrintStream)void printStackTrace(PrintWriter)Throwable fillInStackStrace()void setStackTrace(StackTraceElement[])
Get/set exception causevoid initCause(Throwable)Throwable getCause()
18
Tracing stacksclass 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
Rethrowing= (partly) handle the exception and throw the SAME Exception Object again
Wit
h r
eth
row
i ng
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
Rethrowing
Wit
ho
ut
reth
row
ing
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
Rethrowing
Wit
h r
eth
r ow
ing
& c
ha
ng
i ng
th
e st
ack
tr a
ce
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
Exception causesGOAL : 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 layerProblem
Unknown Exception
Solution
Known Exception
ExceptionA
ExceptionA
ExceptionB• throw new ExceptionB()• ExceptionB e= new ExceptionB(); e.initCause(excepA); throw e;
Cause of
ExceptionB
23
Exception causesclass 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
Nesting tryclass ExceptionA extends Exception {};
class ExceptionB extends Exception {};
class Nesting {
public static void main(String[] args) {
try {
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
The finally clause
try {
} catch( …) {…
} catch( … ) {…
} finally {
…
}
Guaranteed execution
• used for clean-up code• not necessary in C++ (destructor cleans up !)
26
Finally : illustrationimport 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 continue With continue
Inside try.
ExceptionA handler
Inside finally.
Inside try.
Inside finally.
Statement in for-loop.
Inside try.
ExceptionA handler
Inside finally.
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 ifGuaranteed execution is requried
(iteration i=1);
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
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
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{}
}