10.11.2014 Views

Exception Handling in Java

Exception Handling in Java

Exception Handling in Java

SHOW MORE
SHOW LESS

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

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!