Witscale Test Center

5.5 Exceptions > 5.5.2 Defining an exception


5.5.2 Defining an exception

We have discussed how exceptions are handled. We made a simple assumption that the exceptions are objects, without bothering much about the details.  Now is the time to explore further and learn about exceptions as objects.

Exceptions represent erroneous conditions in the program. If you have a particular error condition, you can declare a class to represent it. Every exception in Java is an object of a class of type java.lang.Exception class. Therefore, your class needs to extend this class. The most trivial way  is to just extend the Exception class with no code and let the compiler create the default constructor for you. The following code demonstrates how you can declare your own exception class and how an exception of its type will be handled.

 

public class IncorrectAddressException extends Exception {

}

 

 

public class MailApplication {

 

   void processMail() {

     try {

 

       // process the mail

 

    } catch (IncorrectAddressException exp) {

 

    }

   }

}

 

In our example, the class IncorrectAddressException is derived from Exception. You may recall that the catch clause catches objects of Throwable type. It can also catch the objects of Exception because Exception is a subclass of Throwable. Let us take a close look at the Exception hierarchy. 

 

All programmer-declared exceptions must be the subclasses of Exception class. The important thing about any exception is the class name, as it gives an indication of what went wrong. So most of the time, a bare minimum exception class that only extends Exception is sufficient.

 

Exception hierarchy

All exceptions are objects of class Exception or any of its subclasses. Figure 5.3 illustrates the Java exception hierarchy. It has the java.lang.Throwable class at its top. It has two main subclasses, the Error class and the Exception class.


Figure 5.3 High-level view of the exception hierarchy

 

The subclasses of Error are collectively called as errors. The subclasses of RuntimeException are called as the unchecked exceptions. The subclasses of Exception, which are not subclasses of RuntimeException, are called as the checked exceptions. The following sections discuss the checked and unchecked exceptions as well as errors in detail.

Errors and exceptions

There are two types of classes to represent erroneous conditions in Java, errors and exceptions. Errors are the classes derived from Error and they represent abnormal erroneous conditions. Errors commonly reflect environmental problems such as JVM runs out of memory or memory stack overflows. These problems are difficult to recover from and are beyond your control. As a Java programmer, you need not handle them. Errors are usually handled by the Java system. As you can imagine, errors are rare and usually fatal.

 

Errors are not considered as exceptions in Java, as they are not derived from the Exception class.

 

On the other hand, the exceptions deal with programming-related erroneous conditions. An exception does not mean a syntactic error you do when you write a program. It is usually a legitimate erroneous condition appearing when the assumptions you made while writing your program are violated. For instance, when you read from a file, you assume that it is present. Thus, when it is not found, your program face an anticipated erroneous condition called as an exception.

 

Checked and unchecked exceptions

A checked exception is either a direct or an indirect subclass of Exception excluding the class RuntimeException and its all subclasses. Figure 5.3 shows the checked exceptions in the exception hierarchy.

The checked exceptions are usually the problems that may arise in a correctly coded program. Typical examples are the problems due to incorrect user inputs or irresponsive IO devices. For instance, your program reads a file from a remote computer’s disk and the remote computer is not responding. Now probably there is nothing wrong with your program. It is not working because maybe the network link between your computer and remote computer is down or the disk is inaccessible. These are not the programming problems. However, any good robust program should anticipate these conditions and write a code that handles them. Such anticipated problems are represented with the checked exceptions.

They are called checked as the compiler checks if these exceptions are properly caught or specified. Therefore, the checked exceptions must be either caught or declared at compile time. We will see how to declare an exception in the “throwing exceptions section”. A Few examples of common checked exceptions include FileNotFoundException, SocketException, EOFException.

The unchecked exception classes are the RuntimeException class and all of its subclasses. They typically represent a program bug, such as  when your code try to access array elements out of its bounds, or call some method on a null object. Since these types of bugs are usually result of bad coding, there is nothing the compiler can do. For instance, a unchecked ClassCastException is thrown  at runtime when an object is typecast  to an incompatible type. In the following code sample, anObject is of Integer type. It is cast to a String and therefore an exception is thrown at runtime.

 

Object anObject = new Integer(10);

System.out.println((String) anObject); //ClassCastException thrown

 

These types of bugs should never appear as you are always expected to do good coding. Therefore, the Java compiler does not mandate you to handle them. In other words, these types of exceptions are never checked by the compiler and hence called unchecked exceptions. A Few examples of common unchecked exceptions include the NullPointerException, the ArithmeticExceptionor and the IndexOutOfBoundException.

 

Like the unchecked exceptions the errors are also not checked by compiler. Therefore, you are not required to catch them. In fact, you are never supposed to catch an error. They are usually handled by the JVM itself.