Exception Handling in Java
Exception Handling in Java
Exception Handling in Java
Create successful ePaper yourself
Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.
<strong>Exception</strong> <strong>Handl<strong>in</strong>g</strong> <strong>in</strong> <strong>Java</strong><br />
An exception is an event that occurs dur<strong>in</strong>g the execution of a program that disrupts<br />
the normal flow of <strong>in</strong>structions<br />
<strong>Exception</strong>s are represented as classes <strong>in</strong> <strong>Java</strong>.<br />
Throwable<br />
Error<br />
<strong>Exception</strong><br />
L<strong>in</strong>kageError<br />
VirtualMach<strong>in</strong>eError<br />
(Hardware or System)<br />
RunTime<strong>Exception</strong><br />
Arithmetic<strong>Exception</strong><br />
IndexOutOfBounds<strong>Exception</strong><br />
IllegalAccess<strong>Exception</strong><br />
NegativeArraySize<strong>Exception</strong><br />
1
How is the exception handled?<br />
• ignore it<br />
• handle it where it occurs<br />
• handle it an another place <strong>in</strong> the program<br />
<strong>Exception</strong>: Ignore It<br />
The program will term<strong>in</strong>ate and produce an appropriate message.<br />
public class Zero {<br />
public static void ma<strong>in</strong> (Str<strong>in</strong>g[] args) {<br />
<strong>in</strong>t numerator = 10;<br />
<strong>in</strong>t denom<strong>in</strong>ator = 0;<br />
System.out.pr<strong>in</strong>tln (numerator / denom<strong>in</strong>ator);<br />
System.out.pr<strong>in</strong>tln ("This text will not be pr<strong>in</strong>ted.");<br />
}<br />
}<br />
2
<strong>Exception</strong>: Handle Where It Occurs<br />
<strong>Exception</strong> is represented as an object <strong>in</strong> <strong>Java</strong>. They are thrown by a program, and<br />
may be caught and handled by another part of the program<br />
3
The try and catch Statement<br />
To process an exception when it occurs, the l<strong>in</strong>e that throws the exception is<br />
executed with<strong>in</strong> a try block<br />
A try block is followed by one or more catch clauses, which conta<strong>in</strong> code to process<br />
an exception<br />
Each catch clause has an associated exception type. When an exception occurs,<br />
process<strong>in</strong>g cont<strong>in</strong>ues at the first catch clause that matches the exception type<br />
try {<br />
// Code that might generate exceptions<br />
} catch(Type1 id1) {<br />
// Handle exceptions of Type1<br />
} catch(Type2 id2) {<br />
// Handle exceptions of Type2<br />
} catch(Type3 id3) {<br />
// Handle exceptions of Type3<br />
}<br />
// etc...<br />
4
public class ProductCodes{ // Counts the number of product codes that are<br />
//entered with a zone of R and district greater than 2000.<br />
public static void ma<strong>in</strong> (Str<strong>in</strong>g[] args) {<br />
Str<strong>in</strong>g code;<br />
char zone;<br />
<strong>in</strong>t district, valid = 0, banned = 0;<br />
Scanner scan = new Scanner (System.<strong>in</strong>);<br />
System.out.pr<strong>in</strong>t ("Enter product code (XXX to quit): ");<br />
code = scan.nextL<strong>in</strong>e();<br />
while (!code.equals ("XXX")) {<br />
try {<br />
zone = code.charAt(-9);<br />
district = Integer.parseInt(code.substr<strong>in</strong>g(3, 7));<br />
if (zone == 'R' && district > 2000)<br />
banned++; }<br />
catch (Str<strong>in</strong>gIndexOutOfBounds<strong>Exception</strong> exception){<br />
System.out.pr<strong>in</strong>tln ("Improper code length: " + code);}<br />
catch (NumberFormat<strong>Exception</strong> exception){<br />
System.out.pr<strong>in</strong>tln ("District is not numeric: " + code);}<br />
System.out.pr<strong>in</strong>t ("Enter product code (XXX to quit): ");<br />
code = scan.nextL<strong>in</strong>e();}<br />
System.out.pr<strong>in</strong>tln ("# of valid codes entered: " + valid);<br />
System.out.pr<strong>in</strong>tln ("# of banned codes entered: " + banned);}}<br />
5
The f<strong>in</strong>ally block<br />
A f<strong>in</strong>ally block is where you put code that must run regardless of an exception.<br />
try {<br />
// Dangerous activities that might throw A or B }<br />
catch(A a1) {<br />
// Handler for situation A}<br />
catch(B b1) {<br />
// Handler for situation B}<br />
f<strong>in</strong>ally {<br />
// Activities that happen every time<br />
}<br />
The f<strong>in</strong>ally block is a key tool for prevent<strong>in</strong>g resource leaks. When clos<strong>in</strong>g a file or otherwise<br />
recover<strong>in</strong>g resources, place the code <strong>in</strong> a f<strong>in</strong>ally block to <strong>in</strong>sure that resource is always recovered.<br />
6
Declar<strong>in</strong>g that a method throws exceptions<br />
• The keyword throws <strong>in</strong>dicates that a method can throw an exception that it does not handle.<br />
This declaration does permit another method to handle the exception.<br />
• All <strong>Java</strong> methods use the throw statement to throw an exception. The throw statement requires<br />
a s<strong>in</strong>gle argument: a throwable object.<br />
7
A method can throw more than one exception.<br />
public class Laundry {<br />
public void doLaundry() throws Pants<strong>Exception</strong>, L<strong>in</strong>gerie<strong>Exception</strong> {<br />
// code that could throw either exception<br />
}<br />
}<br />
public class Foo {<br />
public void go() {<br />
Laundry laundry = new Laundry ();<br />
try {<br />
laundry.doLaundry();<br />
} catch(Pants<strong>Exception</strong> pex) {<br />
// recovery code<br />
}<br />
} catch(L<strong>in</strong>gerie<strong>Exception</strong> lex) {<br />
// recovery code<br />
}<br />
8
<strong>Exception</strong>s are polymorphic<br />
You can declare exceptions us<strong>in</strong>g a supertype of the exceptions you throw.<br />
public void doLaundry() throws Cloth<strong>in</strong>g<strong>Exception</strong> //Clos<strong>in</strong>g<strong>Exception</strong> lets you throw<br />
//any subclass of Cloth<strong>Exception</strong>.<br />
9
You can Catch exceptions us<strong>in</strong>g a supertype of the exception thrown.<br />
try {<br />
laundry.doLaundry();<br />
} catch (Cloth<strong>in</strong>g<strong>Exception</strong> cex) {<br />
Can catch any Cloth<strong>in</strong>g<strong>Exception</strong> subclass<br />
try {<br />
laundry.doLaundry();<br />
} catch (Shirt<strong>Exception</strong> cex) {<br />
10
Write a different catch block for each exception that you need to handle uniquely<br />
try {<br />
laundry.doLaundry() ;<br />
} catch (Pants<strong>Exception</strong> tex) {<br />
// recovery from TeeShirt<strong>Exception</strong><br />
} catch (L<strong>in</strong>gerie<strong>Exception</strong> lex) {<br />
// recovery from L<strong>in</strong>gerie<strong>Exception</strong><br />
} catch (Cloth<strong>in</strong>g<strong>Exception</strong> cex) {<br />
// recovery from Cloth<strong>in</strong>g<strong>Exception</strong><br />
}<br />
public class Laundry {<br />
public void doLaundry() throws<br />
Pants<strong>Exception</strong>, L<strong>in</strong>gerie<strong>Exception</strong> {<br />
// code that could throw either exception<br />
}<br />
}<br />
11
<strong>Exception</strong>: Handle it <strong>in</strong> another place <strong>in</strong> the program<br />
If it is not appropriate to handle the exception where it occurs, it can be handled at a higher level<br />
<strong>Exception</strong>s propagate up through the method call<strong>in</strong>g hierarchy until they are caught and handled or<br />
until they reach the outermost level.<br />
public class Propagation {<br />
static public void ma<strong>in</strong> (Str<strong>in</strong>g[] args) {<br />
<strong>Exception</strong>Scope demo = new <strong>Exception</strong>Scope();<br />
demo.level1();}<br />
public class <strong>Exception</strong>Scope{<br />
public void level1() {<br />
try { level2(); }<br />
catch (Arithmetic<strong>Exception</strong> problem) {<br />
System.out.pr<strong>in</strong>tln ("The exception message");}<br />
}<br />
public void level2() {<br />
level3 (); }<br />
public void level3 () {<br />
<strong>in</strong>t numerator = 10, denom<strong>in</strong>ator = 0;<br />
<strong>in</strong>t result = numerator / denom<strong>in</strong>ator; }}<br />
12
Inner try blocks<br />
You can have <strong>in</strong>ner try blocks for specialized exceptions, and reserve the outmost try block for the<br />
exception handl<strong>in</strong>g to use if all the previous attempts fail.<br />
class NestedTryBlocks{<br />
public static void ma<strong>in</strong>(Str<strong>in</strong>g args[]) {<br />
<strong>in</strong>t numer[] = {4, 8, 16, 32, 64, 128, 256, 512};<br />
<strong>in</strong>t denom[] = {2, 0, 4, 4, 0, 8};<br />
try{<br />
for (<strong>in</strong>t i=0; i
class NestedTryBlocks{<br />
public static void ma<strong>in</strong>(Str<strong>in</strong>g args[]) {<br />
<strong>in</strong>t numer[] = {4, 8, 16, 32, 64, 128, 256, 512};<br />
<strong>in</strong>t denom[] = {2, 0, 4, 4, 0, 8};<br />
for (<strong>in</strong>t i=0; i
Rethrow<strong>in</strong>g an exception<br />
If a catch block cannot handle the particular exception it has caught, you can rethrow the exception.<br />
The rethrow expression causes the orig<strong>in</strong>ally thrown object to be rethrown.<br />
Because the exception has already been caught at the scope <strong>in</strong> which the rethrow expression occurs,<br />
it is rethrown out to the next enclos<strong>in</strong>g try block. Therefore, it cannot be handled by catch blocks at<br />
the scope <strong>in</strong> which the rethrow expression occurred. Any catch blocks for the enclos<strong>in</strong>g try block<br />
have an opportunity to catch the exception.<br />
catch(<strong>Exception</strong> e) {<br />
System.out.pr<strong>in</strong>tln("An exception was thrown");<br />
throw e;}<br />
15
public class Rethrow<strong>in</strong>g {<br />
public static void f() throws <strong>Exception</strong> {<br />
System.out.pr<strong>in</strong>tln("orig<strong>in</strong>at<strong>in</strong>g the exception <strong>in</strong> f()");<br />
throw new <strong>Exception</strong>("thrown from f()");<br />
}<br />
public static void g() throws Throwable {<br />
try {<br />
f();<br />
} catch(<strong>Exception</strong> e) {<br />
System.out.pr<strong>in</strong>tln("Inside g()”, e");<br />
throw e;<br />
}<br />
}<br />
orig<strong>in</strong>at<strong>in</strong>g the exception <strong>in</strong> f()<br />
Inside g()”, e<br />
Caught <strong>in</strong> ma<strong>in</strong><br />
public static void ma<strong>in</strong>(Str<strong>in</strong>g[] args) throws Throwable {<br />
try {<br />
g();<br />
} catch(<strong>Exception</strong> e) {<br />
System.out.pr<strong>in</strong>tln("Caught <strong>in</strong> ma<strong>in</strong>");<br />
}<br />
}<br />
}<br />
16
Exercises:<br />
class <strong>Exception</strong>Function {<br />
public static void change( <strong>in</strong>t[] course ) {<br />
System.out.pr<strong>in</strong>tln( "Start Change" );<br />
course[ 10 ] = 1;<br />
System.out.pr<strong>in</strong>tln( "End Change" );}<br />
Start Try<br />
Start Change<br />
OutOfBounds<br />
In F<strong>in</strong>al Block<br />
After try<br />
}<br />
public static void ma<strong>in</strong>( Str<strong>in</strong>g args[] ) {<br />
<strong>in</strong>t students[] = new <strong>in</strong>t[5];<br />
try {<br />
System.out.pr<strong>in</strong>tln( "Start Try" );<br />
change( students );<br />
System.out.pr<strong>in</strong>tln( "After array statement" );}<br />
catch (ArrayIndexOutOfBounds<strong>Exception</strong> e) {<br />
System.out.pr<strong>in</strong>tln( "OutOfBounds");}<br />
f<strong>in</strong>ally {<br />
System.out.pr<strong>in</strong>tln( "In F<strong>in</strong>al Block" );}<br />
System.out.pr<strong>in</strong>tln( " After try " );<br />
}<br />
17
Consider the follow<strong>in</strong>g <strong>Java</strong> code:<br />
try {<br />
System . out . pr<strong>in</strong>tln (1);<br />
try {<br />
System . out . pr<strong>in</strong>tln (2);<br />
f ();<br />
System . out . pr<strong>in</strong>tln (3);}<br />
catch (E1 e1) {<br />
System . out. pr<strong>in</strong>tln (4);}<br />
f<strong>in</strong>ally {<br />
System . out. pr<strong>in</strong>tln (5);}<br />
}<br />
catch (E2 e2) {<br />
System . out . pr<strong>in</strong>tln (6);}<br />
Indicate the output of this code for the cases where (a) there is no exception, (b) f throws<br />
exception E1, (c) f throws exception E2, and (d) f throws exception E3. (Note: E3 is not a subclass<br />
of either E1 and E2.)<br />
Answer:<br />
(a) 1, 2, 3, 5<br />
(b) 1, 2, 4, 5<br />
(c) 1, 2, 5, 6<br />
(d) 1, 2, 5, <strong>Exception</strong><br />
18
Why F<strong>in</strong>ally?<br />
A F<strong>in</strong>ally block will be executed after a try block if no exception has been<br />
thrown or after a catch if an exception was thrown. This means that a f<strong>in</strong>ally<br />
block can be used as 'clean up' - a place to close files or connections etc, whether<br />
an exception is thrown or not.<br />
• If a try block throws an exception and the catch block propagates the<br />
exception (throws it aga<strong>in</strong>), the f<strong>in</strong>ally clause will still execute.<br />
• If the f<strong>in</strong>ally clause executes a return statement, it overides a thrown<br />
exception (so the exception will not be thrown; <strong>in</strong>stead the return will<br />
occur).<br />
19
class ExQ {<br />
public static void ma<strong>in</strong>(Str<strong>in</strong>g[] args) {<br />
try {<br />
System.out.pr<strong>in</strong>tln("Start");<br />
ExQ x = new ExQ();<br />
x.aMethod();<br />
System.out.pr<strong>in</strong>tln("After method");}<br />
catch (<strong>Exception</strong> error) {<br />
System.out.pr<strong>in</strong>tln("ma<strong>in</strong>’s catch");}<br />
f<strong>in</strong>ally {<br />
System.out.pr<strong>in</strong>tln("ma<strong>in</strong>’s f<strong>in</strong>ally");}<br />
System.out.pr<strong>in</strong>tln("End");<br />
}<br />
Start<br />
In aMethod<br />
aMethod’s catch<br />
aMethod’s f<strong>in</strong>ally<br />
ma<strong>in</strong>’s catch<br />
ma<strong>in</strong>’s f<strong>in</strong>ally<br />
End<br />
public void aMethod() throws <strong>Exception</strong> {<br />
try {<br />
System.out.pr<strong>in</strong>tln("In aMethod");<br />
throw new <strong>Exception</strong>();}<br />
catch (<strong>Exception</strong> error ) {<br />
System.out.pr<strong>in</strong>tln("aMethod’s catch");<br />
throw new <strong>Exception</strong>();}<br />
f<strong>in</strong>ally {<br />
System.out.pr<strong>in</strong>tln("aMethod’s f<strong>in</strong>ally");<br />
}<br />
}<br />
}<br />
20
What will be the output of compil<strong>in</strong>g and execut<strong>in</strong>g the ma<strong>in</strong> method of the follow<strong>in</strong>g class?<br />
class ExQ {<br />
public static void ma<strong>in</strong>(Str<strong>in</strong>g[] args) {<br />
try {<br />
System.out.pr<strong>in</strong>tln("Start");<br />
ExQ x = new ExQ();<br />
x.aMethod();<br />
System.out.pr<strong>in</strong>tln("After method");}<br />
catch (<strong>Exception</strong> error) {<br />
System.out.pr<strong>in</strong>tln("ma<strong>in</strong>’s catch");}<br />
f<strong>in</strong>ally {<br />
System.out.pr<strong>in</strong>tln("ma<strong>in</strong>’s f<strong>in</strong>ally");}<br />
System.out.pr<strong>in</strong>tln("End");}<br />
Start<br />
In aMethod<br />
aMethod’s catch<br />
aMethod’s f<strong>in</strong>ally<br />
After method<br />
ma<strong>in</strong>’s f<strong>in</strong>ally<br />
End<br />
public void aMethod() throws <strong>Exception</strong> {<br />
try {<br />
System.out.pr<strong>in</strong>tln("In aMethod");<br />
throw new <strong>Exception</strong>();}<br />
catch (<strong>Exception</strong> error ) {<br />
System.out.pr<strong>in</strong>tln("aMethod’s catch");<br />
throw new <strong>Exception</strong>();}<br />
f<strong>in</strong>ally {<br />
System.out.pr<strong>in</strong>tln("aMethod’s f<strong>in</strong>ally");<br />
return;<br />
}}}<br />
21
<strong>Exception</strong> <strong>Handl<strong>in</strong>g</strong> <strong>in</strong> C++<br />
• Added to C++ <strong>in</strong> 1990<br />
• Design is based on that of Ada, and ML<br />
C++ <strong>Exception</strong> Handlers<br />
try {<br />
throw an actual parameter<br />
}<br />
catch (formal parameter) {<br />
-- handler code }<br />
catch (formal parameter) {<br />
-- handler code<br />
}<br />
• A throw expression accepts one parameter which is passed as an argument to the exception<br />
handler.<br />
• The type of this parameter is very important, s<strong>in</strong>ce the type of the argument passed by the<br />
throw expression is checked aga<strong>in</strong>st it, and only <strong>in</strong> the case they match, the exception is catch.<br />
22
Ex1.<br />
<strong>in</strong>t ma<strong>in</strong> () {<br />
try {<br />
throw 20; }<br />
catch (<strong>in</strong>t e) {<br />
cout
#<strong>in</strong>clude <br />
us<strong>in</strong>g namespace std;<br />
void Xtest(<strong>in</strong>t test) {<br />
cout
A try block could be <strong>in</strong> a function. When this is the case, each time the<br />
function is entered, the exception handl<strong>in</strong>g relative to that function is<br />
reset.<br />
void Xhandler(<strong>in</strong>t test) {<br />
try {<br />
if (test) throw test;}<br />
catch(<strong>in</strong>t i) {<br />
cout
Throw<strong>in</strong>g Objects<br />
class CDtorDemo {<br />
public:<br />
CDtorDemo(){<br />
cout