Thursday 26 May 2011

Exception in java

First Example
The following Demo1 class demonstrates the behaviour of exceptions and applications.
import java.io.*;
class Demo1 {
  public static FileInputStream f1(String fileName)
    throws FileNotFoundException
  {
    FileInputStream fis = new FileInputStream(fileName);
    System.out.println("f1: File input stream created");
    return fis;
  }
  public static FileInputStream f2(String fileName)
  {
    FileInputStream fis = null;
    try
    {
      fis = new FileInputStream(fileName);
    }
    catch (FileNotFoundException ex)
    {
      System.out.println("f2: Oops, FileNotFoundException caught");
    }
    finally
    {
      System.out.println("f2: finally block");
    }
    System.out.println("f2: Returning from f2");
    return fis;
  }
  public static void main(String args[])
  {
    FileInputStream fis1 = null;
    FileInputStream fis2 = null;
    String fileName = "foo.bar";
    // String fileName = null;
    System.out.println(  "main: Starting " + Demo1.class.getName()
                       + " with file name = " + fileName);
    // get file input stream 1
    try {
      fis1 = f1(fileName);
    }
    catch (FileNotFoundException ex)
    {
      System.out.println("main: Oops, FileNotFoundException caught");
    }
    catch (Exception ex)
    {
      System.out.println("main: Oops, genreal exception caught");
    }
    // get file input stream 2
    fis2 = f2(fileName);
    System.out.println("main: " + Demo1.class.getName() + " ended");
  }
}
Compile and run the Demo1 class will generate output as follows (assuming that the file foo.bar does not exist):
main: Starting Demo1 with file name = foo.bar
main: Oops, FileNotFoundException caught
f2: Oops, FileNotFoundException caught
f2: finally block
f2: Returning from f2
main: Demo1 ended
The example program tries to create two file input streams. Therefore two methods f1 and f2 are implemented. First, the main program calls f1 method. Because the constructor of the FileInputStream throws a FileNotFoundException the method f1 must be defined with the throws FileNotFoundException in the method definition. The thrown exception is not handled in the method but forwarded to the invoker. Note, that the system output before the return statement is never executed.
So the invoker, in our example the main program, must catch this exception. The method f1 is called in a try block. The following catch blocks catch either a FileNotFoundException or a general Exception. In our example, the exception is caught in the first catch block and the system output is generated. Since the exception in f1 is caught and handled, the execution of the program is not terminated.
Second, the example program creates another FileInputStream invoking the f2 method. This method catches the FileNotFoundException, so this exception must not be forwarded to the invoker. The try ... catch statement is followed by a finally block. This block is always executed, regardless whether or not an exception occurs within the try block. This generates the system output in our example. Again, the exception is caught and the program executes, this generates the system output in f2 and main.
This was a straight forward example with caught exceptions. What happens with uncaught exceptions? Change the fileName assignment in the main method: Comment out the first assignment and activate the second String fileName = null; then compile and execute Demo1 again. The generated output is:
main: Starting Demo1 with file name = null
main: Oops, genreal exception caught
f2: finally block
java.lang.NullPointerException
java.io.FileInputStream Demo1.f2(java.lang.String)
void Demo1.main(java.lang.String[])
Exception in thread main
This time, we try to create two FileInputStream objects using null instead of a file name. Invoking f1 will generate a NullPointerException which is caught in the main program. Next f2 is called which could handle only the FileNotFoundException but not a NullPointerException. Nevertheless the finally block is executed and then the control returns to the main program. Because there is no try ... catch statement around the call to f2 and no matching catch block is found, the thread is terminated. Note, that f2 and main can not execute the system output statements any more.
Second Example
The second example will show some special behaviour in catch and finally blocks:
import java.io.*;
class Demo2 {
  public static FileInputStream f1(String fileName)
  {
    FileInputStream fis = null;
    try
    {
      fis = new FileInputStream(fileName);
    }
    catch (FileNotFoundException ex)
    {
      System.out.println("f1: Oops, FileNotFoundException caught");
      throw new Error("f1: File not found");
    }
    System.out.println("f1: File input stream created");
    return fis;
  }
  public static FileInputStream f2(String fileName)
  {
    FileInputStream fis = null;
    try
    {
      fis = new FileInputStream(fileName);
    }
    catch (FileNotFoundException ex)
    {
      System.out.println("f2: Oops, FileNotFoundException caught");
      return fis;
    }
    finally
    {
      System.out.println("f2: finally block");
      return fis;
    }
    // Compiler error: statement not reacheable
    // System.out.println("f2: Returning from f2");
    // return fis;

  }
  public static void main(String args[])
  {
    FileInputStream fis1 = null;
    FileInputStream fis2 = null;
    String fileName = "foo.bar";
    // String fileName = null;
    System.out.println(  "main: Starting " + Demo2.class.getName()
                       + " with file name = " + fileName);
    // get file input stream 1
    try {
      fis1 = f1(fileName);
    }
    catch (Exception ex)
    {
      System.out.println("main: Oops, general exception caught");
    }
    catch (Throwable th)
    {
      System.out.println("main: Oops, throwable object caught");
    }
    // get file input stream 2
    fis2 = f2(fileName);
    System.out.println("main: " + Demo2.class.getName() + " ended");
  }
}
}
Compile and run Demo2 will generate the following output:
main: Starting Demo2 with file name = foo.bar
f1: Oops, FileNotFoundException caught
main: Oops, throwable object caught
f2: Oops, FileNotFoundException caught
f2: finally block
main: Demo2 ended

No comments: