Sunday, December 11, 2011

Java Exception Handling Tutorial with Examples


This post explains exception handling in java and suggests best practices for exception handling. An exception in Java is an object that is created when any abnormal, unexpected events or extraordinary conditions occur in program. Handling of those is exception handling in Java. This exception object has data that store information about nature of problem. This exception object is thrown and catch as a parameter.

Exception Inheritance Hierarchy

The possible exceptions in a program are organized in a hierarchy of classes, rooted at class Throwable, a direct subclass of Object. The classes Exception and Error are direct subclasses of Throwable.

The class Exception is the superclass of all the exceptions that ordinary programs may wish to recover from. The class RuntimeException is a subclass of class Exception. The subclasses of RuntimeException are unchecked exception classes. The subclasses of Exception other than RuntimeException are all checked exception classes.

The class Error and its subclasses are exceptions from which ordinary programs are not ordinarily expected to recover. They are all unchecked exception classes.


Type of Exceptions

There are two types of Exceptions.

1. Compile Time Exception alias Checked Exception:  These exceptions are checked by compiler at compile time so they should be either caught or specified. You should compulsorily handle the checked exceptions otherwise code will not be compiled. You should put the code which may cause checked exception in try block.

2. Run Time Exception alias Unchecked Exception: Unchecked exceptions are because of program errors like array index out of bounds, null pointer etc. You need not handle the unchecked exceptions and they will be handled by the JVM.

Java language requires that a method either catch or specify all checked exceptions that can be thrown within the scope of that method.

Few Examples of Checked Exception

IOException, SQLException, FileNotFoundException, MalformedURLException.

Few Examples of Unchecked Exception

ArrayIndexOutOfBoundException, NullPointerException, ClassCastException, NumberFormatException.

Errors

These are not exceptions at all, but problems that arise beyond the control of the user or the programmer. Errors are typically ignored in your code because you can rarely do anything about an error. For example, if a stack overflow occurs, an error will arise. They are also ignored at the time of compilation.

Try this example

We will use this example throughout the post for reference.

import java.io.FileWriter;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.List;
public class ListOfNumbers {
            private List<Integer> list;
            private static final int SIZE = 10;
            public ListOfNumbers() {
                 list = new ArrayList<Integer>(SIZE);
                 for (int i = 0; i < SIZE; i++) {
                        list.add(new Integer(i));
                 }
            }
            public void writeList() {
                  PrintWriter out = new PrintWriter(new FileWriter("OutFile.txt"));
                  for (int i = 0; i < SIZE; i++) {
                           out.println("Value at: " + i + " = " + list.get(i));
                  }
                  out.close();
            }
}

In above code snippet following exceptions are thrown.

Checked Exception: IOException by  new FileWriter("OutFile.txt")

Unchecked Exception: list.get(i) will throw IndexOutOfBoundsException.

Compile Error: Unhandled exception type IOException

Above code will not compile because compiler will print error message about exception thrown by FileWriter but doesn’t display an error message for unchecked exception IndexOutOfBoundsException. Java wants us to either catch checked exception or specify it. Compiler won’t bother about unchecked exceptions.

Why we do not catch RunTime Exceptions?

RunTime Exception represents problems detected by runtime system. They can occur anywhere and anytime and can be numerous. So, as a best practice we neither catch nor specify them.

What does specify an exception mean?

It means if a method chooses not to catch an exception, the method must throw that exception. The throw statement requires a throwable object which is instance of any subclass of Throwable class. If you attempt to throw an object that is not throwable, compiler refuses to compile program and display an error message.

Error message: It must be a subclass of class java.lang.Throwable

How exception are thrown or specified?

If a method does not handle a checked exception, the method must declare it using the throws keyword.

public void writeList() {
                        PrintWriter out = new PrintWriter(new FileWriter("OutFile.txt"));
                        for (int i = 0; i < SIZE; i++) {
                                    out.println("Value at: " + i + " = " + list.get(i));
                        }
                        out.close();
}

This method won't compile by design because compiler will print error message about exception thrown by FileWriter. If method doesn't catch the checked exceptions that can occur within it, the writeList method must specify that it can throw these exceptions.

Modify it to throw IOException rather catching it. Add a throws clause to the method declaration for the writeList method. The throws clause comprises the throws keyword followed by a comma-separated list of all the exceptions thrown by that method. The clause goes after the method name and argument list and before the brace that defines the scope of the method, here's an example.

public void writeList() throws IOException {
                        PrintWriter out = new PrintWriter(new FileWriter("OutFile.txt"));
                        for (int i = 0; i < SIZE; i++) {
                                    out.println("Value at: " + i + " = " + list.get(i));
                        }
                        out.close();
}

Handling Exceptions in Java

Exception handling in Java is done using the try, catch, and finally blocks. A try block encloses code that may give risk to one or more exception. In general, a try block looks like the following:

try {
   code
}

A catch block encloses code that will be executed when an exception is thrown in try block. A catch block must immediately follow try block. The try and catch block are bonded together and we must not separate them by putting statement between two blocks. We can’t have just a try block by itself. If a try block throws several exceptions we can put several catch block after try block to handle them.

try {
} catch (ExceptionType name) {
} catch (ExceptionType name) {
}

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 clean up code accidentally bypassed by a return, continue, or break. Putting clean up code in a finally block is always a good practice, even when no exceptions are anticipated.

Each try block must always be followed by at least one block that is either catch or finally block.

The following finally block for the writeList method cleans up and then closes the PrintWriter.

finally {
     if (out != null) {
         System.out.println("Closing PrintWriter");
         out.close();
     } else {
         System.out.println("PrintWriter not open");
     }
}

Putting All Together

After putting try, catch, finally block, the writeList method looks like the following.

public void writeList() {
    PrintWriter out = null;
    try {
        System.out.println("Entering try statement");
        out = new PrintWriter(
                          new FileWriter("OutFile.txt"));
            for (int i = 0; i < SIZE; i++)
                out.println("Value at: " + i + " = "
                             + vector.elementAt(i));
                 
    } catch (ArrayIndexOutOfBoundsException e) {
         System.err.println("Caught "
                     + "ArrayIndexOutOfBoundsException: "
                     +   e.getMessage());
                                 
    } catch (IOException e) {
         System.err.println("Caught IOException: "
                             +  e.getMessage());
                                
    } finally {
         if (out != null) {
             System.out.println("Closing PrintWriter");
             out.close();
               
         }
         else {
             System.out.println("PrintWriter not open");
         }
     }
}

Proper order of catch blocks in a Java program to catch exceptions

The catch block must be in sequence with the most desired type first and the most basic type last otherwise code will not compile. Catching of exception should be lower to higher in inheritance hierarchy.

Assume that there are exception classes namely A whose super is B who in turn has a super C
then the order of catching them is

try
{
}
catch (A ex1)
{
}
catch (B ex2)
{
}
catch (C ex3) //most generic has to be caught last or all others will be suppressed.
{
}

How to log exceptions?

Logging exception is a good practice to follow. Looking at exception stack trace helps a developer to troubleshoot an error quickly and efficiently. Following two methods prints full exception stack trace.

void printStackTrace() : It displays a single line of text describing the current exception followed by stacktrace.

void printStackTrace(PrintWriter writer) : It is same as the previous method but the output will be redirected to an output screen or file.

Design and throw our own Exception

A really useful feature is the ability to create custom exception classes and throw one of our own exceptions. We will discuss it in detail in next post.

That’s all folks. Leave your comments. Continue Reading!


1 Responses to “Java Exception Handling Tutorial with Examples”

extremejava said...
December 14, 2011 at 12:18 PM

The only thing I miss in above tutorial is Custom Exceptions and Disadvantage of Exceptions


Post a Comment

© 2011 a2ztechguide.com • All rights reserved.
Blogger Template by Bloggermint