Docstoc

Java Exception Handling

Document Sample
Java Exception Handling Powered By Docstoc
					                  Basics concepts of Java Exception Handling




TABLE OF CONTENTS

1. Purpose......................................................................................................................... 2
2. Audience ...................................................................................................................... 2
3. Introduction .................................................................................................................. 2
4. The Nature of Exceptions ............................................................................................ 3
5. Types of Exceptions in Java ........................................................................................ 4
6. The Call Stack Explained............................................................................................. 5
7. Catching Exceptions .................................................................................................... 7
       The try Block ....................................................................................................... 7
       The catch Blocks .................................................................................................. 7
8. The Throwable Superclass ......................................................................................... 10
9. Finally ........................................................................................................................ 11
10. Advantages of Exceptions........................................................................................ 13
11. Best Practices for Using Exceptions ........................................................................ 14
12.Summary ................................................................................................................... 17
13.References ................................................................................................................. 18
14.Feedback & Comments ..........................................Error! Bookmark not defined.20
1. Purpose

 This document is prepared to provide a basic understanding of exception handling in
 java applications. This document is helpful for the java beginners.

2. Audience

 This document is prepared keeping java beginners in mind.


3. Introduction

 Exception handling is a very important yet often neglected aspect of writing robust
 software.

 The term exception is shorthand for the phrase "exceptional event."

 An exception is an error thrown by a class or method reporting an error in operation.

 When an error occurs in a Java program it usually results in an exception being thrown.
 How you throw, catch and handle these exception matters. There are several different
 ways to do so. Not all are equally efficient and fail safe.

 For example, dividing by zero is undefined in mathematics, and a calculation can fail if
 this winds up being the case because of an error in user input. In this particular case an
 ArithmeticException is thrown, and unless the programmer looks for this exception and
 manually puts in code to handle it, the program will crash stating the exception thrown
 and a stack trace, which would be unhelpful to a casual user of a Java program. If the
 programmer handles the exception, he could deliver a useful error to the user and return
 the user to the beginning of the program so that they could continue to use it.
4. The Nature of Exceptions

 Broadly speaking, there are three different situations that cause exceptions to be
 thrown:

       Exceptions due to programming errors: In this category, exceptions are
        generated due to programming errors (e.g., NullPointerException and
        IllegalArgumentException). The client code usually cannot do anything about
        programming errors.



       Exceptions due to client code errors: Client code attempts something not
        allowed by the API, and thereby violates its contract. The client can take some
        alternative course of action, if there is useful information provided in the
        exception. For example: an exception is thrown while parsing an XML
        document that is not well-formed. The exception contains useful information
        about the location in the XML document that causes the problem. The client can
        use this information to take recovery steps.



       Exceptions due to resource failures: Exceptions that get generated when
        resources fail. For example: the system runs out of memory or a network
        connection fails. The client's response to resource failures is context-driven. The
        client can retry the operation after some time or just log the resource failure and
        bring the application to a halt.
5. Types of Exceptions in Java




Java defines two kinds of exceptions:

      Checked exceptions: Exceptions that inherit from the Exception class are
       checked exceptions. Client code has to handle the checked exceptions thrown
       by the API, either in a catch clause or by forwarding it outward with the throws
       clause.



      Unchecked exceptions: RuntimeException also extends from Exception.
       However, all of the exceptions that inherit from RuntimeException get special
       treatment. There is no requirement for the client code to deal with them, and
       hence they are called unchecked exceptions.

By way of example, Figure 1 shows the hierarchy for NullPointerException.
6. The Call Stack Explained

By the call stack is meant the sequence of method calls from the current method and
back to the Main method of the program.

When an error occurs within a method, the method creates an object and hands it off to
the runtime system. The object, called an exception object, contains information
about the error, including its type and the state of the program when the error
occurred. Creating an exception object and handing it to the runtime system is
called throwing an exception.

After a method throws an exception, the runtime system attempts to find something to
handle it. The set of possible "something’s" to handle the exception is the ordered list
of methods that had been called to get to the method where the error occurred. The list
of methods is known as the call stack (see the next figure).




The call stack.

The runtime system searches the call stack for a method that contains a block of code
that can handle the exception. This block of code is called an exception handler. The
search begins with the method in which the error occurred and proceeds through the
call stack in the reverse order in which the methods were called. When an appropriate
handler is found, the runtime system passes the exception to the handler. An exception
handler is considered appropriate if the type of the exception object thrown matches the
type that can be handled by the handler.
The exception handler chosen is said to catch the exception. If the runtime system
exhaustively searches all the methods on the call stack without finding an appropriate
exception handler, as shown in the next figure, the runtime system (and, consequently,
the program) terminates.




                  Searching the call stack for the exception handler.
7. Catching Exceptions

The java language contains keywords used specifically for testing for and handling
exceptions. The ones we will be using here are try and catch, and they must be used in
conjunction with one another. They sort of work like if-else:

try{
  /*
   Contains code to be tested
  */
}catch(Exception e){
  /*
   Contains code to be executed if instanced of Exception is caught
  */
}


The catch statement can look for all exceptions, using the Exception superclass, or it
can catch a specific exception that you think could be thrown in the code you are
testing with the try block. You can even have multiple catch blocks to catch and
execute custom code for a number of different errors. A good thing to note would be
that any particular exception that is caught is compared with each catch statement
sequentially; so it is a good idea to put more generic exceptions, like Exception,
towards the bottom of the list.



   The try Block

The first step in constructing an exception handler is to enclose the code that might
throw an exception within a try block. In general, a try block looks like the following.
try {
   code
}
catch and finally blocks . . .


   The catch Blocks

You associate exception handlers with a try block by providing one or more catch
blocks directly after the try block. No code can be between the end of the try block and
the beginning of the first catch block.


try {
} catch (ExceptionType name) {

} catch (ExceptionType name) { }
Each catch block is an exception handler and handles the type of exception indicated by
its argument. The argument type, ExceptionType, declares the type of exception that the
handler can handle and must be the name of a class that inherits from the Throwable
class. The handler can refer to the exception with name.

The catch block contains code that is executed if and when the exception handler is
invoked. The runtime system invokes the exception handler when the handler is the
first one in the call stack whose ExceptionType matches the type of the exception
thrown. The system considers it a match if the thrown object can legally be assigned to
the exception handler's argument.

Catching the exception is done using a try-catch block. Here is an example: public
void callDivide(){


try {


          int result = divide(2,1);


         System.out.println(result);


     } catch (BadNumberException e) {


         //do something clever with the exception


         System.out.println(e.getMessage());


     }


     System.out.println("Division attempt done");


}
The BadNumberException parameter e inside the catch-clause points to the exception
thrown from the divide method, if an exception is thrown.

If no exception is thrown by any of the methods called or statements executed inside
the try-block, the catch-block is simply ignored. It will not be executed.

If an exception is thrown inside the try-block, for instance from the divide method, the
program flow of the calling method, callDivide, is interrupted just like the program
flow inside divide. The program flow resumes at a catch-block in the call stack that can
catch the thrown exception. In the example above the "System.out.println (result);"
statement will not get executed if an exception is thrown from the divide method.
Instead program execution will resume inside the "catch (BadNumberException e) { }"
block.

If an exception is thrown inside the catch-block and that exception is not caught, the
catch-block is interrupted just like the try-block would have been.

When the catch block is finished the program continues with any statements following
the catch block. In the example above the "System.out.println ("Division attempt
done");" statement will always get executed.
    8. The Throwable Superclass

    The catch statement also stores an instance of the exception that was caught in the
    variable that the programmer uses, in the previous example Exception e. While all
    exceptions are subclasses of Exception, Exception itself is a subclass of Throwable,
    which contains a nice suite of methods that you can use to get all kinds of information
    to report about your exceptions:

           getMessage()--returns the error message reported by the exception in a String
           printStackTrace()--prints the stack trace of the exception to standard output,
      useful for debugging purposes in locating where the exception occurred
           printStackTrace(PrintStream s)--prints the stack trace to an alternative output
      stream
           printStackTrace(PrintWriter s)--prints the stack trace to a file, this way you can
      log stack traces transparent to the user or log for later reference
           toString()--if you just decide to print out the exception it will print out this:
      NAME_OF_EXCEPTION: getMessage().

    Using the catch you now have control over what the error message is and where it goes.

    If a method needs to be able to throw an exception, it has to declare the exception(s)
    thrown in the method signature, and then include a throw-statement in the method. Here
    is an example: public void divide(int numberToDivide, int numberToDivideBy)


      throws BadNumberException{


          if(numberToDivideBy == 0){


              throw new BadNumberException("Cannot divide by 0");


          }


          return numberToDivide / numberToDivideBy;


      }


    When an exception is thrown the method stops execution right after the "throw"
    statement. Any statements following the "throw" statement are not executed. In the
example above the "return numberToDivide / numberToDivideBy;" statement is not
executed if a BadNumberException is thrown. The program resumes execution when
the exception is caught somewhere by a "catch" block. Catching exceptions is
explained later.

You can throw any type of exception from your code, as long as your method signature
declares it. You can also make up your own exceptions. Exceptions are regular Java
classes that extends java.lang.Exception, or any of the other built-in exception classes.
If a method declares that it throws an exception A, then it is also legal to throw
subclasses of A.

9. Finally
The finally block always executes when the try block exits. This ensures that the finally
block is executed even if an unexpected exception occurs. But finally is useful for more
than just exception handling — it allows the programmer to avoid having cleanup code
accidentally bypassed by a return, continue, or break. Putting cleanup code in a finally
block is always a good practice, even when no exceptions are anticipated.

You can attach a finally-clause to a try-catch block. The code inside the finally clause
will always be executed, even if an exception is thrown from within the try or catch
block. If your code has a return statement inside the try or catch block, the code inside
the finally-block will get executed before returning from the method. Here is how a
finally clause looks:


  public void openFile(){


FileReader reader = null;


     try {


        reader = new FileReader("someFile");


        int i=0;


        while (i != -1){


             i = reader.read();


             System.out.println((char) i );
          }


      } catch (IOException e) {


          //do something clever with the exception


      } finally {


          if(reader != null){


              try {


                  reader.close();


              } catch (IOException e) {


                  //do something clever with the exception


              }


          }


          System.out.println("--- File End ---");


      }


  }


No matter whether an exception is thrown or not inside the try or catch block the code
inside the finally-block is executed. The example above shows how the file reader is
always closed, regardless of the program flow inside the try or catch block.


Note: If the JVM exits while the try or catch code is being executed, then the finally
block may not execute. Likewise, if the thread executing the try or catch code is
interrupted or killed, the finally block may not execute even though the application as a
whole continues.


Important: The finally block is a key tool for preventing resource leaks. When closing
a file or otherwise recovering resources, place the code in a finally block to ensure that
resource is always recovered.




10. Advantages of Exceptions

Now that you know what exceptions are and how to use them, it's time to learn the
advantages of using exceptions in your programs.

1: Separating Error-Handling Code from "Regular" Code
Exceptions provide the means to separate the details of what to do when something out
of the ordinary happens from the main logic of a program. In traditional programming,
error detection, reporting, and handling often lead to confusing spaghetti code.

2: Propagating Errors Up the Call Stack

A second advantage of exceptions is the ability to propagate error reporting up the call
stack of methods. Suppose that the readFile method is the fourth method in a series of
nested method calls made by the main program: method1 calls method2, which calls
method3, which finally calls readFile.
method1 {
   call method2;
}

method2 {
  call method3;
}

method3 {
  call readFile;
}

Suppose also that method1 is the only method interested in the errors that might occur
within readFile. Traditional error-notification techniques force method2 and method3 to
propagate the error codes returned by readFile up the call stack until the error codes
finally reach method1—the only method that is interested in them.


3: Grouping and Differentiating Error Types

Because all exceptions thrown within a program are objects, the grouping or
categorizing of exceptions is a natural outcome of the class hierarchy. An example of a
group of related exception classes in the Java platform are those defined in java.io —
IOException and its descendants. IOException is the most general and represents any
type of error that can occur when performing I/O. Its descendants represent more
specific errors.

11. Best Practices for Using Exceptions

The next set of best practices show how the client code should deal with an API that
throws checked exceptions.
1. Always clean up after yourself

If you are using resources like database connections or network connections, make sure
you clean them up. If the API you are invoking uses only unchecked exceptions, you
should still clean up resources after use, with try - finally blocks.

public void dataAccessCode(){
  Connection conn = null;
  try{
     conn = getConnection();
     ..some code that throws SQLException
  }catch(SQLException ex){
     ex.printStacktrace();
  } finally{
     DBUtil.closeConnection(conn);
  }
}

class DBUtil{
   public static void closeConnection
     (Connection conn){
     try{
        conn.close();
     } catch(SQLException ex){
        logger.error("Cannot close connection");
        throw new RuntimeException(ex);
     }
   }
}

DBUtil is a utility class that closes the Connection. The important point is the use of
finally block, which executes whether or not an exception is caught. In this example,
the finally closes the connection and throws a RuntimeException if there is problem
with closing the connection.

2. Never use exceptions for flow control

Generating stack traces is expensive and the value of a stack trace is in debugging. In a
flow-control situation, the stack trace would be ignored, since the client just wants to
know how to proceed.

In the code below, a custom exception, MaximumCountReachedException, is used to
control the flow.

public void useExceptionsForFlowControl() {
    try {
       while (true) {
          increaseCount();
       }
    } catch (MaximumCountReachedException ex) {
    }
    //Continue execution
}

public void increaseCount()
  throws MaximumCountReachedException {
  if (count >= 5000)
     throw new MaximumCountReachedException();
}

The useExceptionsForFlowControl() uses an infinite loop to increase the count until the
exception is thrown. This not only makes the code difficult to read, but also makes it
slower. Use exception handling only in exceptional situations.

3. Do not suppress or ignore exceptions

When a method from an API throws a checked exception, it is trying to tell you that
you should take some counter action. If the checked exception does not make sense to
you, do not hesitate to convert it into an unchecked exception and throw it again, but do
not ignore it by catching it with {} and then continue as if nothing had happened.

4. Do not catch top-level exceptions

Unchecked exceptions inherit from the RuntimeException class, which in turn inherits
from Exception. By catching the Exception class, you are also catching
RuntimeException as in the following code:



try{
..
}catch(Exception ex){
}

The code above ignores unchecked exceptions, as well.

5. Log exceptions just once

Logging the same exception stack trace more than once can confuse the programmer
examining the stack trace about the original source of exception. So just log it once.
12.Summary

A program can use exceptions to indicate that an error occurred. To throw an exception,
use the throw statement and provide it with an exception object — a descendant of
Throwable — to provide information about the specific error that occurred. A method
that throws an uncaught, checked exception must include a throws clause in its
declaration.

A program can catch exceptions by using a combination of the try, catch, and finally
blocks.

The try block identifies a block of code in which an exception can occur.
The catch block identifies a block of code, known as an exception handler, that can
handle a particular type of exception.

The finally block identifies a block of code that is guaranteed to execute, and is the
right place to close files, recover resources, and otherwise clean up after the code
enclosed in the try block.

The try statement should contain at least one catch block or a finally block and may
have multiple catch blocks.

The class of the exception object indicates the type of exception thrown. The exception
object can contain further information about the error, including an error message. With
exception chaining, an exception can point to the exception that caused it, which can in
turn point to the exception that caused it, and so on.



13.References

Google search engine (http://www.google.com) is used to search and analyze
information before writing this document.
http://onjava.com/onjava/2003/11/19/exceptions.html
http://www.osix.net/modules/article/?id=754
http://tutorials.jenkov.com/java-exception-handling/basic-try-catch-finally.html
http://tutorials.jenkov.com/java-exception-handling/index.html
http://java.sun.com/docs/books/tutorial/essential/exceptions/catchOrDeclare.html

				
DOCUMENT INFO