You are on page 1of 5

Exceptions

Java's way of defensive programming is via the use of its exceptions mechanism. Exceptions has the
following two benefits:
_ They allow you to separate error handling code from normal code.
_ You can determine exactly who handles an error. There is a well defined chain of responsibility;
exception travel up the method callstack until it is handled by one of the method. Unhandle
exception are captured and reported by the JVM.

An exception is an event thrown either by the JVM or by your code to indicate that an error has occured.
We will begin our exception discussion by learing how to glean useful information for exception stacks.
We will then proceed to looking at Java exception mechanism; we will end this chapter by creating our
very own exceptions.

An Exceptional Example
Let's look at the following code
1 import java.lang.*;
2
3 public class ExceptionEx {
4 public String[] msgs = {"bonjour", "chou san",
5 "selamat pagi" };
6 public void doit() {
7 int i = 0;
8 while (i < msgs.length)
9 System.out.println(msgs[++i]);
10 }
11 public static void main(String[] args) {
12 ExceptionEx ex = new ExceptionEx();
13 ex.doit();
14 }
15 }

which will generate the following exception stack example when executed:

1 chou san
2 selamat pagi
3 java.lang.ArrayIndexOutOfBoundsException: 3
4 at ExceptionEx.doit(ExceptionEx.java:9)
5 at ExceptionEx.main(ExceptionEx.java:13)

The stack consists of 2 parts, line 3 indicates the type of exception that has occured and lines 4 and 5
shows the methods on the call stack. The exception type is ArrayIndexOutOfBoundsException which
occurs in doit() method at line 9 in the ExceptionEx.java _le. Notice how the exception “travels" from doit()
to main() until it reaches the JVM which prints out the exception.
Examining line 9 we find the offending line:

System.out.println(msgs[++i]);

Apparently the programmer should have written i++ instead of ++i which resulted in the exception.

Exception Objects
A exception object is an object that represents the state of the exception. When an exception occurs the
JVM captures the environment at that instance. This captured information is the exception object. You
can examine the exception object to find out what is wrong and recover from it. All exception objects are
subclass of Exception and has the following methods:

public void printStackTrace()


Prints out the stack trace at the point of the exception.
public String getMessage()
Returns the exception's error message, if any
try-catch Block
A try-catch block establishes a block of code that is to have its exception and abnormal exits handled. A catch
established what exception that the block should catch and take whatever action necessary to deal with the
exceptional condition. The syntax of a try-catch block is as follows:

try {
<exception_block>
} catch (<exception_class> e) {
<exception_handler>
}
Lets look at a try-catch block; we will rewrite the example to handle the ArrayIndexOutOfBoundsException and
recover from it.
1 ...
2 public void doit() {
3 int i = 0;
4 while (i < msgs.length)
5 try {
6 System.out.println(msgs[++i]);
7 } catch (ArrayIndexOutOfBoundsException e) {
8 System.out.println("Oops! Busted index. Reseting");
9 i = 0;
10 }
11 }
12 ...
The explanation for the exception code snippet is as follows:

line 5 to 7, These lines define the exception block, viz. the block of code that could generate an exception. Our block
of code consist of 1 single line vis. the { } between lines 5 and 7.

line 7, The catch defines what exception to catch. This is specified as a formal parameter immediately after catch. If
such an exception is raised in the exception block, program control is passed to the exception handler. Notice that
the catch block looks a lot like a method declaration. Also, note the ”e". This is the exception object.

chou san
selamat pagi
Oops! Busted index. Reseting
chou san
selamat pagi
Oops! Busted index. Reseting
chou san
selamat pagi

When i equals to 3, line 6 of the code snippet above generated an exception; the exception object is
caught by catch and the exception handler is executed. We see the “Oops!" message printed out and i s
reset to 0. When the exception handler completes, the program returns to while and the entire process is
repeated.

You can catch multiple exception within an exception block. This is done by adding multiple catch to the
exception block; the previous code snippet is modified to catch 2 exceptions as below:
1 ...
2 public void doit() {
3 int i = 0;
4 while (i < msgs.length)
5 try {
6 System.out.println(msgs[++i]);
7 } catch (ArrayIndexOutOfBoundsException e) {
8 System.out.println("Oops! Busted index. Reseting");
9 i = 0;
10 } catch (NullPointerException e) {
11 System.out.println("Oops! Did not initialize array");
12 break;
13 }
14 }
15 ...

When an exception is thrown in a multi catch blocks, it is caught by the first catch block with the
appropriate exception object type. Only one catch block will be executed. Please note that the previous
code snippet has a bug in the array access. You should always correct a bug rather than using a try-catch
to circumvent it.

And finally...

The finally keyword is generally used to clean up after a try or a catch. It defines a block of code that is
always executed regardless of whether an

exception is thrown. This is also true when you execute a return, continue or break. Lets take a look at an
example:
1 ...
2 public void readFile(String file) {
3 FileInputStream fis = null;
4 int ch;
5 try {
6 fis = new FileInputStream(file);
7 while ((ch = is.read()) != -1)
8 System.out.println(ch);
9 } catch (IOException e) {
10 System.out.println(e.getMessage());
11 } finally {
12 is.close();
13 }
14 }
15 ...

Line 7 reads a character for a FileInputStream. The read() method may throw a IOException if it
encountered an error during the read. But regardless of whether an IOExceptiion exception is thrown or
not, the above code snippet will guarantee to close the _le because we have the close() ( line 12) in a
finally block.

There are 4 possible scenarios to a try-catch-finally block. They are

Forced exit is when you forced program control to be passed out of a try block. This is done using a
return, continue or break.

Normal completion is when the code in a try-catch-finally block completes normally.

Caught exception thrown refers to an exception thrown that is specified in a catch.

Uncaught exception thrown is when an exception is thrown and this exception is not speci_ed in a
catch. This category of exception is almost always a RuntimeException. If we have the following code
skeleton

try {
// Point 1
} catch ( . . .) {
// Point 2
} finally {
// Point 3
}
// Point 4

Declaring Exceptions
Sometimes you may not choose to handle an exception but pass it on the calling method. In this case you
must declare the out going exception as part of your method declaration. The readFile() method is
modified so that the caller instead of readFile() is responsible for handling IOException.
1 ...
2 public void readFile(String file)
3 throws IOException {
4 FileInputStream fis = null;
5 try {
6 int ch;
7 fis = new FileInputStream(file);
8 while ((ch = is.read()) != -1)
9 System.out.println(ch);
10 } finally {
11 is.close();
12 }
13 }
14 . . .
Note line 3, you use throws to declare that there is an exception to be caught. It is the responsibility of the
caller to handle it within a try-catch block.

8.1.6 Generating Exceptions


You can generate your own exception with a throw (note the missing “s") statement. A throw does 2
things:

1. Creates an exception object.


2. Causes normal program execution to stop.

This above 2 points is best illustrated with the following example:

1 ...
2 public void readFile(String file)
3 throws IOException, FileNotFoundException {
4 FileInputStream fis = null;
5 File fd = new File(file);
6 if (!fd.exists())
7 throw new FileNotFoundException(file);
8 try {
9 int ch;
10 fis = new FileInputStream(file);
11 while ((ch = is.read()) != -1)
12 System.out.println(ch);
13 }finally {
14 is.close();
15 }
16 }
17 ...

The explanation for the above code is as follows: we check if the _le exists; if it exists we proceed to open
and read it. But if it does not exists, we throw a FileNotFoundException (line 7). Notice that you have to
instantiate the exception object. After the throw statement, the program exist the readFile() method. The
remaining statements in the method are not executed.

Creating Your Own Exception

Besides using the JDK supplied exception classes, you can also create your own exception objects. This
requires you to subclass the Exception class. We will add exception to Account class. We will modify
OverdrawnException to withdrawal() method. The OverdrawnException will capture all information
pertaining to an overdrawn Transaction.

These information includes the following:

_ Account name.
_ Account number.
_ Account balance at the time of the withdrawal.
_ Overdrawn amount.
_ The date of the transaction.

The following code implements OverdrawnException.

1 import java.lang.*;
2 import java.util.*;
3 public class OverdrawnException
4 extends Exception {
5 private final String name;
6 private final int acctNo;
7 private final float balance;
8 private final float withdrawAmount;
9 private final Date date;
10 public OverdrawnException(Account acct, float amt) {
11 super("Overdrawn");
12 name = acct.getName();
13 acctNo = acct.getAccountNumber();
14 balance = acct.getBalance();
15 withdrawnAmount = amt;
16 date = new Date();
17 }
18 public String getName() {
19 return (name);
20 }
21 ...
22 public float getWithdrawAmount() {
23 return (withdrawAmount);
24 }
25 }

The explanation for the above code is as follows:

line 10, The constructor takes an Account object and initializes the account name (name), account
number (acctNo) and current balance (balance). The amt holds the amount the the user is attempting to
withdraw. Note that these members are marked final. This means that the value of these members cannot
be changed. What we are really saying here is that OverdrawnException object is immtable; once create,
the content of the object cannot be changed.
line 11, Since the superclass has a constructor with a String parameter. You can get this message using
the getMessage() method.

line 12 to 16, are read only properties to name, account number, balance, amount attempted to withdraw
and the transcation date. To use OverdrawnException, we modify withdrawal() of Account class as
follows:

1 public class Account {


2 ...
3 public void withdrawal(float amt)
4 throws OverdrawnException, ErroneousAmountException {
5 if (amt > balance)
6 throw new OverdrawnException(this, amt);
7 if ((amt < 0)
8 throw new ErroneousAmountException(this, amt);
9 balance -= amt;
10 }
11 ...
12 }

line 4, Declares OverdrawnException and ErroneousAmountException will be thrown from withdrawal().


Assme ErroneousAmountException is defined.

line 6, If the amount to be withdrawn is greater than what is in the account, we throw the
OverdrawnException, passing to it all the necessary parameters.

line 7, 8, We check if we are withdrawing negative amount. If so we throw a di_erent exception.

line 9,When we have passed all the necessary checks, we do the withdraw.

The following code snippet show how we use the modified withdrawal().

1 ...
2 try {
3 account.withdraw(amt);
4 } catch (OverdrawnException e) {
5 System.out.println("Overdrawn");
6 System.out.println("You have: " + e.getBalance());
7 System.out.println("You attempt to withdraw: "
8 + e.getWithdrawAmount());
9 }

You might also like