6.5 Checked and Unchecked Exceptions

 < Day Day Up > 



6.5 Checked and Unchecked Exceptions

In Java programs some exceptions have to be explicitly handled and some exceptions do not have to be explicitly handled. This is often confusing to programmers unfamiliar with Java exceptions. The rationale for this behavior is that some exceptions and errors can almost always occur, and when programmers acknowledge this reality in the code the program becomes unwieldy without producing any positive effect. However, some errors, such as trying to open a nonexistent file, are sufficiently limited in scope and important enough to require the programmer to acknowledge that they might occur and to make allowances for them.

The tradeoff between programmers acknowledging and specifically handling all errors or handling only a limited number of important errors is a very nice feature of Java. Some programmers react badly to a language forcing them to acknowledge anything, and they often write programs such the one shown in Exhibit 3 (Program6.3) out of ignorance, haste, or a simple refusal to handle errors. Java programs are much safer because the types of errors that occur in Exhibit 3 (Program6.3) must be explicitly handled or propagated, or their not being handled must at least be acknowledged. This is shown in Exhibit 11 (Program6.7), which shows the Java program equivalent to Exhibit 3 (Program6.3). Note that the exceptions for opening and writing to a file cannot simply be ignored in the program, so the program will produce a correct error if any problems are encountered.

Exhibit 11: Program6.7: Java Program Equivalent to C Exhibit 3 (Program6.3)

start example

 import java.io.FileReader; import java.io.BufferedReader; import java.io.IOException; public class PrintFile {   public static void main(String args[]) {     try {       FileReader fr = new FileReader("tmp.dat");       BufferedReader br = new BufferedReader(fr);       String s = br.readLine();       while (s ! = null) {         System.out.println(s);         s = br.readLine();       }     } catch(IOException ioe) {       ioe.printStackTrace();     }   } } 

end example

6.5.1 Exception Hierarchy

Exceptions that are limited as to where they can occur and thus are handled in a program are referred to as checked exceptions. Exceptions that do not have to be handled are called unchecked exceptions. To understand the difference between checked and unchecked exceptions it is necessary to understand how Java groups exceptions and errors. Exhibit 12 provides a hierarchy chart of some of the exceptions in Java. In Java, all exceptions are objects and extend from a base class Throwable, which provides the basic functions such as printStackTrace and getMessage. The hierarchy is then broken down into three categories: Error, RuntimeException, and Exception. Each of these is described in more detail below.

Exhibit 12: Java Exception Hierarchy

start example

click to expand

end example

  • Errors are normally problems in the JVM that are outside of the programmer's control and would probably cause the program to quit running. They can occur anywhere in the program. For example, an OutOfMemoryError occurs in the JVM if for any reason it cannot satisfy a memory request. This could mean that a program on the computer has a memory leak, all the memory on the system has been used up, and the computer must be rebooted; this situation is something the programmer cannot do anything about. Another problem is a VerifyError that says that the ".class" file being read has some type of internal inconsistency such as an invalid check sum. This could mean that the file has been hacked and malicious code inserted so it should not be run.

  • RuntimeExceptions are problems that are the result of the logic or implementation of a program and potentially can occur anywhere in a program. For example, an ArrayIndexOutOfBoundsException occurs when a program attempts to read or write an array position not in the array. This error is the result of the program not properly handling the array indexing and could be fixed by the programmer either by correcting the code or possibly in a catch block in the program.

  • Exceptions are problems in the program caused by the logic or implementation of the program but are generally limited in scope. For example, a FileNotFoundException is thrown when an attempt is made to open a file that does not exist. This type of error occurs only when a call is made to a method to open a file, so it is generated by an explicit action in the program and is limited to the open method call.

Any exception or error class that is an ancestor of another class can be used to catch an exception. For example, IOException is the parent of both the FileNotFoundException and the EOFException and therefore can be used as a surrogate in a catch block for either of these exceptions. Further, Exception is the parent of IOException, so it can be used as a surrogate for any IOException, as well as any other exception for which it is an ancestor. So, when creating a file, a FileNotFoundException must be caught, which can be achieved by a FileNotFoundException, an IOException, or simply an Exception.

6.5.2 Checked and Unchecked Exceptions

Checked exceptions are exceptions that must be either explicitly caught or thrown. These are the exceptions that cause the message "exception must be explicitly caught or thrown" when compiling a program. Errors or exceptions that are descendants of class Error or RuntimeException are unchecked, and they do not have to be explicitly caught or thrown. Any other exceptions must be handled.

A checked exception can be handled in two ways. The first is to use a catch block to handle the exception, and the second is to explicitly propagate the exception to the calling method. Exhibits 13 and 14 (Program6.8 and Program6.9) illustrate both of these points. In Exhibits 13 and 14 (Program6.8 and Program6.9), the constructor for the FileInputStream throws a check exception, FileNotFoundException. In Exhibit 13 (Program6.8), this exception is caught in a try block that encloses the constructor class. Note that, because a FileNotFound-Exception is also an IOException, an Exception, and a Throwable, catching any of these would handle this exception. In Exhibit 14 (Program6.9), the FileNotFoundException is handled by explicitly throwing an IOException. Once again, because the FileNotFoundException extends the IOException, this statement explicitly allows the IOException to be thrown.

Exhibit 13: Program6.8: Catching a Checked Exception

start example

 import java.io.FileInputStream; import java.io.FileNotFoundException; public class CatchImmediate {   public FileInputStream openFile(String fileName) {     FileInputStream fis = null;     try {       fis = (new FileInputStream(fileName));     } catch(FileNotFoundException fnfe) {       fnfe.printStackTrace();     }     return fis;   } } 

end example

Exhibit 14: Program6.9: Throwing a Checked Exception

start example

 import java.io.FileInputStream; import java.io.IOException; /**  *  There are two ways to handle a checked exception. The second  *  is to explicitly propagate it.  This program shows  *  propagating the FileNotFoundException by having the method  *  throw the exception rather than handle it. Note that the  *  method throws an IOException, not a FileNotFoundException.  *  But, because the IOException is the parent of the  *  FileNotFoundException, it can be used as a proxy for the  *  exception. Note that only the FileNotFoundException can ever  *  be thrown, but by using the IOException the calling method  *  must now handle the IOException.  */ public class Propagate {   public FileInputStream openFile(String fileName) throws       IOException {     return new FileInputStream(fileName);   } } 

end example

Checked and unchecked exceptions confuse many programmers. If an unchecked exception can occur or even if it is explicitly thrown, it does not have be explicitly handled. Exhibit 15 (Program6.10) shows that even though an ArithmeticException is explicitly thrown by the method f1 it does not have to be caught in the main method. This is because it is not the presence of an exception in a throws clause that determines if the exception must be checked or not, but the type of exception.

Exhibit 15: Program6.10: Explicit ArithmeticException That Does Not Have to Be Handled

start example

 public class NotChecked {   public static void throwUnchecked() throws ArithmeticExcep- tion       {     int i = 0, j = 7, k;     k = j/i;   }   public static void main(String args[]) {     //Note that no try block is needed to call method.     throwUnchecked();   } } 

end example

Checked exceptions must be declared with a throws clause as part of the method signature for a method, so it is easy to check the Javadoc to see what exceptions are thrown and must be handled. However, often the easiest way to figure out if an exception needs to be caught in a program is simply to code the function up and see if the compiler generates any messages or to use an Integrated Development Environment (IDE) that automatically inserts the necessary catch clause.



 < Day Day Up > 



Creating Components. Object Oriented, Concurrent, and Distributed Computing in Java
The .NET Developers Guide to Directory Services Programming
ISBN: 849314992
EAN: 2147483647
Year: 2003
Pages: 162

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net