October 25, 2014
Hot Topics:
RSS RSS feed Download our iPhone app

The Essence of OOP using Java, Exception Handling

  • September 3, 2002
  • By Richard G. Baldwin
  • Send Email »
  • More Articles »

You have a choice

Therefore, when writing exception handlers, you have a choice.  You can write a handler whose exception type corresponds to a node in the inheritance hierarchy, and it will be appropriate to catch exceptions of that type, or any subclass of that type.

Alternately, you can write a handler whose exception type corresponds to a leaf, in which case, it will be appropriate to catch exceptions of that type only.

And finally, you can mix and match, writing some exception handlers whose type corresponds to a node, and other exception handlers whose type corresponds to a leaf.  In all cases, however, be sure to position your exception handlers in reverse subclass order, with the furthermost subclass from the root appearing first, and the root class appearing last.

The finally block

And finally (no pun intended), Campione and Walrath tell us:

"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."

To elaborate, the finally block can be used to provide a mechanism for cleaning up open files, etc., before allowing control to be passed to a different part of the program.  You accomplish this by writing the cleanup code within a finally block.

Code in finally block is always executed

It is important to remember that the runtime system always executes the code within the finally block regardless of what happens within the try block.

If no exceptions are thrown, none of the code in catch blocks is executed, but the code in the finally block is executed.

If an exception is thrown and the code in an exception handler is executed, once the execution of that code is complete, control is passed to the finally block and the code in the finally block is executed.

(There is one important exception to the above.  If the code in the catch block terminates the program by executing System.exit(0), the code in the finally block will not be executed.)

The power of the finally block

The sample program shown in Listing 5 illustrates the power of the finally block.
 

/*File Excep15.java
Copyright 2002, R. G. Baldwin

Tested with JDK 1.4.0 under Win2000
**************************************/

class Excep15{
  public static void main(
                        String[] args){
    new Excep15().aMethod();
  }//end main
  //---------------------------------//
                          
  void aMethod(){
    try{
      int x = 5/0;
    }//end try block
    catch(ArithmeticException e){
      System.out.println(
      "In catch, terminating aMethod");
      return;
    }//end catch block
    
    finally{
      System.out.println(
            "Executing finally block");
    }//end finally block

    System.out.println(
                "Out of catch block");
  }//end aMethod

}//end class Excep15 

Listing 5

Execute return statement in catch block

The code in Listing 5 forces an ArithmeticException by attempting to do an integer divide by zero.  Control is immediately transferred to the matching catch block, which prints a message and then executes a return statement.

Normally, execution of a return statement terminates the method immediately.  In this case, however, before the method terminates and returns control to the calling method, the code in the finally block is executed.  Then control is transferred to the main method, which called this method in the first place.

Figure 8 shows the output produced by this program.
 

In catch, terminating aMethod
Executing finally block

Figure 8

This program demonstrates that the finally block really does have the final word.

Declaring exceptions thrown by a method

Sometimes it is better to handle exceptions in the method in which they are detected, and sometimes it is better to pass them up the call stack and let another method handle them.

In order to pass exceptions up the call stack, you must declare them in your method signature.

To declare that a method throws one or more exceptions, you add a throws clause to the method signature for the method. The throws clause is composed of the throws keyword followed by a comma-separated list of all the exceptions thrown by that method.

The throws clause goes after the method name and argument list and before the curly bracket that defines the scope of the method.

Figure 9 shows the syntax for declaring that a method throws four different types of exceptions.
 

void myMethod() throws 
          InterruptedException, 
          MyException, 
          HerException, 
          UrException
{
  //method code
}//end myMethod()

Figure 9

Assuming that these are checked exceptions, any method calling this method would be required to either handle these exception types, or continue passing them up the call stack. Eventually, some method must handle them or the program won't compile.

(Note however that while it might not represent good programming practice, it is allowable to declare that the main method throws exceptions.  This is a way to avoid handling checked exceptions and still get your program to compile.)

The throw keyword

Before your code can catch an exception, some Java code must throw one. The exception can be thrown by code that you write, or by code that you are using that was written by someone else.

Regardless of who wrote the code that throws the exception, it's always thrown with the Java throw keyword.  At least that is true for exceptions that are thrown by code written in the Java language.

(Exceptions such as ArithmeticException are also thrown by the runtime system, which is probably not written using Java source code.)

A single argument is required

When formed into a statement, the throw keyword requires a single argument, which must be a reference to an object instantiated from the Throwable class, or any subclass of the Throwable class.  Figure 10 shows an example of such a statement.
 

throw new myThrowableClass("Message");

Figure 10

If you attempt to throw an object that is not instantiated from Throwable or one of its subclasses, the compiler will refuse to compile your program.

Defining your own exception classes

Now you know how to write exception handlers for those exception objects that are thrown by the runtime system, and thrown by methods in the standard class library.

It is also possible for you to define your own exception classes, and to cause objects of those classes to be thrown whenever an exception occurs.  In this case, you get to decide just what constitutes an exceptional condition.

For example, you could write a data-processing application that processes integer data obtained via a TCP/IP link from another computer.  If the specification for the program indicates that the integer value 10 should never be received, you could use an occurrence of the integer value 10 to cause an exception object of your own design to be thrown.

Choosing the exception type to throw

Before throwing an exception, you must decide on its type.  Basically, you have two choices in this regard:

  • Use an exception class written by someone else, such as the myriad of exception classes defined in the Java standard library.
  • Define an exception class of your own.

An important question

So, an important question is, when should you define your own exception classes and when should you use classes that are already available.  Because this is only one of many design issues, I'm not going to try to give you a ready answer to the question.  However, I will refer you to The Java Tutorial by Campione and Walrath where you will find a checklist to help you make this decision.

Choosing a superclass to extend

If you decide to define your own exception class, it must be a subclass of Throwable. You must decide which class you will extend.

The two existing subclasses of Throwable are Exception and Error. Given the earlier description of Error and its subclasses, it is not likely that your exceptions would fit the Error category. (In concept, errors are reserved for serious hard errors that occur deep within the system.)

Checked or unchecked exception

Therefore, your new class should probably be a subclass of Exception.  If you make it a subclass of RuntimeException, it won't be a checked exception.  If you make it a subclass of Exception, but not a subclass of RuntimeException, it will be a checked exception.

Only you can decide how far down the Exception hierarchy you want to go before creating a new branch of exception classes that are unique to your application.

Naming conventions

Many Java programmers append the word Exception to the end of all class names that are subclasses of Exception, and append the word Error to the end of all class names that are subclasses of Error.

One more sample program

Let's wrap up this lesson with one more sample program named Excep16.  We will define our own exception class in this program. Then we will throw, catch and process an exception object instantiated from that class.

Discuss in fragments

This program is a little longer than the previous programs, so I will break it down and discuss it in fragments.  A complete listing of the program is shown in Listing 10.

The class definition shown in Listing 6 is used to construct a custom exception object that encapsulates a message.  Note that this class extends Exception(Therefore, it is a checked exception.)
 

class MyException extends Exception{
  MyException(String message){//constr
    super(message);
  }//end constructor
}//end MyException class

Listing 6

The constructor for this class receives an incoming String message parameter and passes it to the constructor for the superclass.  This makes the message available for access by the getMessage method invoked in the catch block.

The try block

Listing 7 shows the beginning of the main method, including the entire try block
 

class Excep16{//controlling class
  public static void main(
                        String[] args){
    try{
      for(int cnt = 0; cnt < 5; cnt++){
        //Throw a custom exception, and
        // pass  message when cnt == 3
        if(cnt == 3) throw 
                  new MyException("3");
        //Transfer control before 
        // processing for cnt == 3
        System.out.println(
           "Processing data for cnt = "
                                + cnt);
      }//end for-loop
    }//end try block

Listing 7

The main method executes a for loop (inside the try block) that guarantees that the variable named cnt will reach a value of 3 after a couple of iterations.

Once during each iteration, (until the value of cnt reaches 3) a print statement inside the for loop displays the value of cnt.  This results in the output shown in Figure 11.
 

Processing data for cnt = 0
Processing data for cnt = 1
Processing data for cnt = 2

Figure 11

What happens when cnt equals 3?

However, when the value of cnt equals 3, the throw statement highlighted in boldface in Listing 7 is executed.  This causes control to transfer immediately to the matching catch block following the try block (see Listing 8).  During this iteration, the print statement following the throw statement is not executed.  Therefore, the output never shows a value for cnt greater than 2, as shown in Figure 11.

The catch block

Listing 8 shows a catch block whose type matches the type of exception thrown in Listing 7.
 

    catch(MyException e){
      System.out.println(
               "In exception handler, "
                  + "get the message\n"
                     + e.getMessage());
    }//end catch block

Listing 8

When the throw statement is executed in Listing 7, control is transferred immediately to the catch block in Listing 8.  No further code is executed within the try block.

A reference to the object instantiated as the argument to the throw keyword in Listing 7 is passed as a parameter to the catch block.  That reference is known locally by the name e inside the catch block.

Using the incoming parameter

The code in the catch block invokes the method named getMessage (inherited from the Throwable class) on the incoming parameter and displays that message on the screen.  This produces the output shown in Figure 12.
 

In exception handler, get the message
3

Figure 12

When the catch block finishes execution ...

When the code in the catch block has completed execution, control is transferred to the first executable statement following the catch block as shown in Listing 9.
 

    System.out.println(
      "Out of catch block");
  }//end main
}//end class Excep16


Listing 9

That executable statement is a print statement that produces the output shown in Figure 13.
 

Out of catch block

Figure 13

A complete listing of the program is shown in Listing 10.
 

/*File Excep16.java  
Copyright 2002, R. G. Baldwin
Illustrates defining, throwing, 
catching, and processing a custom 
exception object that contains a 
message.

Tested using JDK 1.4.0 under Win 2000

The output is:

Processing data for cnt = 0

Processing data for cnt = 1
Processing data for cnt = 2
In exception handler, get the message
3
Out of catch block
**************************************/

//The following class is used to 
// construct a customized exception 
// object containing a message
class MyException extends Exception{
  MyException(String message){//constr
    super(message);
  }//end constructor
}//end MyException class
//===================================//

class Excep16{//controlling class
  public static void main(
                        String[] args){
    try{
      for(int cnt = 0; cnt < 5; cnt++){
        //Throw a custom exception, and
        // pass  message when cnt == 3
        if(cnt == 3) throw 
                  new MyException("3");
        //Transfer control before 
        // processing for cnt == 3
        System.out.println(
           "Processing data for cnt = "
                                + cnt);
      }//end for-loop
    }//end try block
    catch(MyException e){
      System.out.println(
               "In exception handler, "
                  + "get the message\n"
                     + e.getMessage());
    }//end catch block
    //-------------------------------//
    
    System.out.println(
      "Out of catch block");
  }//end main

Listing 10

Summary

This lesson has covered many of the details having to do with exception handling in Java.  By now, you should know that the use of exception handling is not optional in Java, and you should have a pretty good idea how to use exception handling in a beneficial way.

Along the way, the discussion has included the following topics:

  • What is an exception?
  • How do you throw and catch exceptions?
  • What do you do with an exception once you have caught it?
  • How do you make use of the exception class hierarchy provided by the Java development environment?

What's Next?

For the time being, that completes the miniseries entitled "The Essence of OOP using Java."  I may decide to come back later and add some lessons on inner classes and other similar topics, but it will probably be a while before I get around to that.  In the meantime, I sincerely hope that you have enjoyed this miniseries, and have found the lessons useful in your continuing effort to learn and understand OOP as implemented using Java.


Copyright 2002, Richard G. Baldwin.  Reproduction in whole or in part in any form or medium without express written permission from Richard Baldwin is prohibited.

About the author

Richard Baldwin is a college professor (at Austin Community College in Austin, Texas) and private consultant whose primary focus is a combination of Java, C#, and XML. In addition to the many platform and/or language independent benefits of Java and C# applications, he believes that a combination of Java, C#, and XML will become the primary driving force in the delivery of structured information on the Web.

Richard has participated in numerous consulting projects, and he frequently provides onsite training at the high-tech companies located in and around Austin, Texas.  He is the author of Baldwin's Programming Tutorials, which has gained a worldwide following among experienced and aspiring programmers. He has also published articles in JavaPro magazine.

Richard holds an MSEE degree from Southern Methodist University and has many years of experience in the application of computer technology to real-world problems.

baldwin@DickBaldwin.com

-end-
 





Page 3 of 3



Comment and Contribute

 


(Maximum characters: 1200). You have characters left.

 

 


Sitemap | Contact Us

Rocket Fuel