Showing posts with label try-catch. Show all posts
Showing posts with label try-catch. Show all posts

Sunday, March 13, 2011

The finally Block in java

The final step in setting up an exception handler is providing a mechanism for cleaning up the state of the method before (possibly) allowing control to be passed to a different part of the program. You do this by enclosing the cleanup code within a finally block.
The try block of the writeList method that you've been working with opens a PrintWriter. The program should close that stream before allowing control to pass out of the writeList method. This poses a somewhat complicated problem because writeList's try block has three different exit possibilities:
  1. The new FileWriter statement failed and threw an IOException.
  2. The victor.elementAt(i) statement failed and threw an ArrayIndexOutOfBoundsException.
  3. Everything succeeded and the try block exited normally.
The runtime system always executes the statements within the finally block regardless of what happens within the try block. Regardless of whether control exits the writeList method's try block due to one of the three scenarios listed previously, the code within the finallyblock will be executed.This is the finally block for the writeList method. It cleans up and closes the PrintWriter.
finally {
    if (out != null) { 
        System.out.println("Closing PrintWriter");
        out.close(); 
    } else { 
        System.out.println("PrintWriter not open");
    } 
} 

Is the finally Statement Really Necessary?

At first the need for a finally statement may not be immediately apparent. Programmers often ask "Is the finally statement really necessary or is it just sugar for my Java?" In particular, C++ programmers doubt the need for a finally statement because C++ doesn't have one.The need for a finally statement is not apparent until you consider the following: how does the PrintWriter in the writeListmethod get closed if you don't provide an exception handler for the ArrayIndexOutOfBoundsException and anArrayIndexOutOfBoundsException occurs? (It's easy and legal to omit an exception handler for ArrayIndexOutOfBoundsExceptionbecause it's a runtime exception and the compiler won't alert you that the writeList contains a method call that might throw one.) The answer is that the PrintWriter does not get closed if an ArrayIndexOutOfBoundsException occurs and writeList does not provide a handler for it--unless the writeList provides a finally statement.
There are other benefits to using the finally statement. In the writeList example it is possible to provide for cleanup without the intervention of a finally statement. For example, you could put the code to close the PrintWriter at the end of the try block and again within the exception handler for ArrayIndexOutOfBoundsException, as shown here:
try {
    . . .
    out.close();       // don't do this; it duplicates code 
} catch (ArrayIndexOutOfBoundsException e) {
    out.close();       // don't do this; it duplicates code 
    System.err.println("Caught ArrayIndexOutOfBoundsException: " + e.getMessage());
} catch (IOException e) {
    System.err.println("Caught IOException: " + e.getMessage());
}
However, this duplicates code, making the code hard to read and prone to errors if you modify the code later. For example, if you add code to the try block that may throw a new type of exception, you will have to remember to close thePrintWriter within the new exception handler (which if you're anything like me, you are bound to forget).

The catch Block(s)

The try statement defines the scope of its associated exception handlers. You associate exception handlers with a try statement by providing one or more catch blocks directly after the try block:
try {
    . . . 
} catch ( . . . ) {
    . . . 
} catch ( . . . ) {
    . . . 
} . . . 
There can be no intervening code between the end of the try statement and the beginning of the first catch statement. The general form of Java's catch statement is:
catch (SomeThrowableObject variableName) {
    Java statements
}
As you can see, the catch statement requires a single formal argument. The argument to the catch statement looks like an argument declaration for a method. The argument type, SomeThrowableObject, declares the type of exception that the handler can handle and must be the name of a class that inherits from the Throwable class defined in the java.lang package. When Java programs throw an exception they are really just throwing an object, and only objects that derive from Throwable can be thrown. You'll learn more about throwing exceptions in How to Throw Exceptions.variableName is the name by which the handler can refer to the exception caught by the handler. For example, the exception handlers for the writeList method (shown later) each call the exception's getMessage method using the exception's declared name e:
e.getMessage()
You access the instance variables and methods of exceptions in the same manner that you access the instance variables and methods of other objects. getMessage is a method provided by the Throwable class that prints additional information about the error that occurred. The Throwable class also implements two methods for filling in and printing the contents of the execution stack when the exception occurred. Subclasses of Throwable can add other methods or instance variables. To find out what methods an exception implements, check its class definition and definitions for any of its ancestor classes.The catch block contains a series of legal Java statements. These statements are 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 type matches that of the exception thrown.
The writeList method from the ListOfNumbers class uses two exception handlers for its try statement, with one handler for each of the two types of exceptions that can be thrown within the try block -- ArrayIndexOutOfBoundsException and IOException.
try {
    . . . 
} catch (ArrayIndexOutOfBoundsException e) {
    System.err.println("Caught ArrayIndexOutOfBoundsException: " +
		        e.getMessage());
} catch (IOException e) {
    System.err.println("Caught IOException: " +
		        e.getMessage());
}

Catching Multiple Exception Types with One Handler

The two exception handlers used by the writeList method are very specialized. Each handles only one type of exception. The Java language allows you to write general exception handlers that handle multiple types of exceptions.As you know, Java exceptions are Throwable objects; they are instances of Throwable or a subclass of Throwable. The Java packages contain numerous classes that derive from Throwable and thus, build a hierarchy of Throwable classes.
Your exception handler can be written to handle any class that inherits from Throwable. If you write a handler for a "leaf" class (a class with no subclasses), you've written a specialized handler: it will only handle exceptions of that specific type. If you write a handler for a "node" class (a class with subclasses), you've written a general handler: it will handle any exception whose type is the node class or any of its subclasses.Let's modify the writeList method once again. Only this time, let's write it so that it handles both IOExceptions andArrayIndexOutOfBoundsExceptions. The closest common ancester of IOException and ArrayIndexOutOfBoundsException is the Exceptionclass. An exception handler that handles both types of exceptions looks like this:
try {
    . . .
} catch (Exception e) {
    System.err.println("Exception caught: " + e.getMessage());
}
The class is pretty high in the Throwable class hierarchy. So in addition to the IOException and ArrayIndexOutOfBoundsExceptiontypes that this exception handler is intended to catch, it will catch numerous other types. Generally speaking, your exception handlers should be more specialized. Handlers that can catch most or all exceptions are typically useless for error recovery because the handler has to determine what type of exception occurred anyway to determine the best recovery strategy. Also, exception handlers that are too general can make code more error prone by catching and handling exceptions that weren't anticipated by the programmer and for which the handler was not intended.

The try Block in java

The first step in constructing an exception handler is to enclose the statements that might throw an exception within a try block. In general, a try block looks like this:
try {
    Java statements
}
The segment of code labelled Java statements is composed of one or more legal Java statements that could throw an exception.To construct an exception handler for the writeList method from the ListOfNumbers class, you need to enclose the exception-throwing statements of the writeList method within a try block. There is more than one way to accomplish this task. You could put each statement that might potentially throw an exception within its own try statement, and provide separate exception handlers for each try. Or you could put all of the writeList statements within a single try statement and associate multiple handlers with it. The following listing uses one try statement for the entire method because the code tends to be easier to read.
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 + " = " + victor.elementAt(i));
}
The try statement governs the statements enclosed within it and defines the scope of any exception handlers associated with it. In other words, if an exception occurs within the try statement, that exception is handled by the appropriate exception handler associated with this try statement.A try statement must be accompanied by at least one catch block or one finally block.

Catching and Handling Exceptions in java using try-catch-finally

The syntax for the usage of try, catch and finally block is given below.

try{
//some java statements which can throw exception
???
}
catch(<exceptionclass1> <obj1>){
//deal with exception
}
finally{
//close open streams etc...
}


 

We have already seen the class which has to deal with the exception here.

Now that you've familiarized yourself with the ListOfNumbers class and where the exceptions can be thrown within it, you can learn how to write exception handlers to catch and handle those exceptions.
The three sections that follow cover the three components of an exception handler -- the try, catch, and finally blocks. So dealing with exceptions one by one :


 

The try Block


The first step in writing an exception handler is to enclose the statements that might throw an exception within a try block. The try block is said to govern the statements enclosed within it and defines the scope of any exception handlers (established by subsequent catch blocks) associated with it.

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 + " = " + victor.elementAt(i));
}
The try statement governs the statements enclosed within it and defines the scope of any exception handlers associated with it.
Now if Exception is thrown, it should be handled by catch block or the finally block. So lets see next section.

 

The catch Block(s)



Next, you associate exception handlers with a try block by providing one or more catch blocks directly after the try block. You associate exception handlers with a try statement by providing one or more catch blocks directly after the try block:


try {
. . .
} catch ( ExceptionClass1 obj1. . ) {
. . .
} catch ( . . . ) {
. . .
}


The finally Block


Java's finally block provides a mechanism that allows your method to clean up after itself regardless of what happens within the try block. Use the finally block to close files or release other system resources.

Putting It All Together


The previous sections describe how to construct the try, catch, and finally code blocks for the writeList example. Now, let's walk through the code and investigate what happens during three scenarios.

Saturday, March 12, 2011

The throw Statement

Syntax of throw

All Java methods use the throw statement to throw an exception. The throw statement requires a single argument: a throwable object. In the Java system, throwable objects are instances of any subclass of the Throwable class. Here's an example of a throw statement:
throw someThrowableObject;


What if object is not Throwable ?

If you attempt to throw an object that is not throwable, the compiler refuses to compile your program and displays an error message similar to the following:

testing.java:10: Cannot throw class java.lang.Integer; it must be a subclass of class java.lang.Throwable.
throw new Integer(4);
^

The next page, The Throwable Class and Its Subclasses, talks more about the Throwable class.

 

Example



Let's look at the throw statement in context. The following method is taken from a class that implements a common stack object. The pop method removes the top element from the stack and returns it:


public Object pop() throws EmptyStackException {
Object obj;
if (size == 0)
throw new EmptyStackException();
obj = objectAt(size - 1);
setObjectAt(size - 1, null);
size--;
return obj;
}

The pop method checks to see if there are any elements on the stack. If the stack is empty (its size is equal to 0), then pop instantiates a new EmptyStackException object and throws it. The EmptyStackException class is defined in the java.util package. Later pages in this lesson describe how you can create your own exception classes. For now, all you really need to remember is that you can throw only objects that inherit from the java.lang.Throwable class.

The throws Clause





You'll notice that the declaration of the pop method contains this clause:



throws EmptyStackException

The throws clause specifies that the method can throw an EmptyStackException. As you know, the Java language requires that methods either catch or specify all checked exceptions that can be thrown within the scope of that method. You do this with the throws clause of the method declaration. For more information about this requirement see Java's catching or throwing exception. Also, Specifying the Exceptions Thrown by a Method shows you in more detail how a method can specify the exceptions it can throw.

 





throw vs throws


See here for the difference between throw and throws.

Chitika