Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Ganesh_JavaSE7_Programming_1z0-804_study_guide.pdf
Скачиваний:
94
Добавлен:
02.02.2015
Размер:
5.88 Mб
Скачать

Chapter 11 Exceptions and Assertions

Exception Types

Until now, we have focused on explaining the language constructs related to exceptions: the try, catch, multi-catch, finally, and try-with-resources blocks. Some concepts won’t be clear to you yet. For example, you learned the throws clause where you declare that a method can throw certain exceptions. You saw that for some types of exceptions, you don’t need to declare them in the throws clause, but for certain other kinds of exceptions, you can declare them in the throws clause. Why? What are these different kinds of exceptions? To answer these questions and get a better idea about the exception handling support in the Java library, we’ll discuss types of exceptions in this section.

In Java, you cannot throw any primitive types as exception objects. This does not mean that you can throw any reference type objects as exceptions. The thrown object should be an instance of the class Throwable or one of its subclasses: Throwable is the apex class of the exception hierarchy in Java. Exception handling constructs such as the throw statement, throws clause, and catch clause deal only with Throwable and its subclasses. There are three important subclasses of Throwable that you need to learn in detail: the Error, Exception, and RuntimeException classes. Figure 11-2 provides a high-level overview of these classes.

 

java.lang.Object

 

Base class of checked

 

 

Base of exception

exceptions such as

java.lang.Throwable

hierarchy;all

ParseException and

exceptions must

 

 

IOException;you must

 

 

extent this class.

handle them!

 

 

 

 

java.lang.Exception

java.lang.Error

 

java.lang.RuntimeException

Base class for representing programming errors such as IndexOutOFBoundsException.

JVM errors such as stackOverflowError; don’t

handle them!

Figure 11-2.  Java’s exception hierarchy

The Exception Class

Exceptions of type Exception are known as checked exceptions. If code can throw an Exception, you must handle it using a catch block or declare that the method throws that exception, forcing the caller of that method to handle that exception. Consider Listing 11-12.

Listing 11-12.  CheckedExceptionExample1.java

import java.io.*;

class CheckedExceptionExample1 {

        public static void main(String []args) {

                FileInputStream fis = new FileInputStream(args[0]);

        }

}

336

Chapter 11 Exceptions and Assertions

This program results in a compiler error.

CheckedExceptionExample1.java:5: error: unreported exception FileNotFoundException; must be caught or declared to be thrown

FileInputStream fis = new FileInputStream(args[0]);

          ^

1 error

The constructor of FileInputStream declares that it throws the exception FileNotFoundException. This FileNotFoundException is derived from the Exception class, hence is a checked exception. With checked exceptions, Java forces you to think about failure conditions and how to handle them. Now, think about the code in Listing 11-13: you are trying to open the file given by the string args[0], which may not be present. If you don’t want to catch and handle the FileNotFoundException, you can declare the main() method to throw this exception.

Listing 11-13.  CheckedExceptionExample2.java

import java.io.*;

class CheckedExceptionExample2 {

        public static void main(String []args) throws FileNotFoundException {

                FileInputStream fis = new FileInputStream(args[0]);

        }

}

This program will compile fine without any errors. However, this code is still not satisfactory: if you pass the name of a file in the command line that does not exist in the search path, the program will crash after throwing this exception:

D:\ > java CheckedExceptionExample2 somefile.txt

Exception in thread "main" java.io.FileNotFoundException: somefile.txt (The system cannot find the file specified)

at java.io.FileInputStream.open(Native Method)

at java.io.FileInputStream.<init>(FileInputStream.java:138) at java.io.FileInputStream.<init>(FileInputStream.java:97)

at CheckedExceptionExample2.main(CheckedExceptionExample2.java:5)

A better way to handle the situation is to throw an error message to the user and inform her that she has to pass the file name as the first argument to the program, as in Listing 11-14.

Listing 11-14.  CheckedExceptionExample3.java

import java.io.*;

class CheckedExceptionExample3 {

        public static void main(String []args) {

                try {

                        FileInputStream fis = new FileInputStream(args[0]);

                } catch(FileNotFoundException fnfe) {

System.out.println("Error: There is no file that exists with name " + args[0]);

System.out.println("Pass a valid file name as commandline argument!");

                }

        }

} 

337

Chapter 11 Exceptions and Assertions

Now, when passed with a name of the file that does not exist, the program will terminate and show this useful error message to the user:

D:\ > java CheckedExceptionExample3 somefile.txt

Error: There is no file that exists with name somefile.txt Pass a valid file name as commandline argument! 

If you have some code that can throw a checked exception from a method, you can choose between the two alternatives. You can either handle that exception by providing a catch block or declare that method to throw that exception. If you don’t catch or declare the method to throw that exception, your code won’t compile.

Table 11-1 summarizes the important subclasses of the Exception class.

Table 11-1.  Important Subclasses of the Exception Class

 

 

Class

Short Description

CloneNotSupportedException

Thrown when the clone() method is invoked on an object whose class

 

does not implement a Cloneable interface.

IOException

Thrown when an Input/Output operation fails (say because of an

 

interrupted call).

EOFException

Thrown when end-of-file (EOF) is reached unexpectedly; subclass of

 

IOException.

FileNotFoundException

Thrown when the runtime is not able to locate or open the given file;

 

derived class of IOException.

ReflectiveOperationException

Thrown when a reflection operation fails; superclass of reflection

 

related exceptions such as NoSuchMethodException and

 

InvocationTargetException.

RuntimeException

Superclass of unchecked exceptions (discussed in the next section in this

 

chapter).

SQLException

Thrown when a database access or related operations fail; superclass of

 

database-related exceptions such as SerialException.

ParseException

Thrown when the parsing fails (for example, while processing locale-

 

sensitive information such as dates and times in the Format class).

 

 

The RuntimeException Class

RuntimeException is a derived class of the Exception class. The exceptions deriving from this class are known as unchecked exceptions. Let’s first discuss an example of a RuntimeException. Recollect Listing 11-14 in the context of FileNotFoundException (we’ve renamed the class in Listing 11-15).

338

Chapter 11 exCeptions and assertions

Listing 11-15. UnCheckedExceptionExample1.java

import java.io.*;

class UnCheckedExceptionExample1 {

public static void main(String []args) throws FileNotFoundException { FileInputStream fis = new FileInputStream(args[0]);

}

}

What happens if you run the program without passing any arguments to this program? It will crash after throwing an ArrayIndexOutOfBoundsException.

Exception in thread "main" java.lang.ArrayIndexOutOfBoundsException: 0

at UnCheckedExceptionExample1.main(UnCheckedExceptionExample1.java:5)

In this program, without checking the length of args (to see if it contains any values), you attempt indexing args in the expression args[0]. In other words, you assume that the user will always provide the name of the file to open as a command-line argument, and when no argument is provided, it becomes an exceptional condition. Hence, it

is a programming mistake. Note that though the expression args[0] can throw ArrayIndexOutOfBoundsException, you did not catch this exception or declare it in the throws clause of the main() method. This is because

ArrayIndexOutOfBoundsException is a RuntimeException, so it is an unchecked exception.

it is optional to handle unchecked exceptions. if a code segment you write in a method can throw an unchecked exception, it is not mandatory to catch that exception or declare that exception in the throws clause of that method.

How can you fix the problem in Listing 11-15? How about the following change in the program to handle the

ArrayIndexOutOfBoundsException (shown in Listing 11-16)?

Listing 11-16. UnCheckedExceptionExample2.java

import java.io.*;

class UnCheckedExceptionExample2 {

public static void main(String []args) throws FileNotFoundException { try {

FileInputStream fis = new FileInputStream(args[0]); } catch (ArrayIndexOutOfBoundsException aioobe) {

System.out.println("Error: No arguments passed in the commandline!"); System.out.println("Pass the name of the file to open as commandline argument");

}

}

}

339

Chapter 11 Exceptions and Assertions

When run, this program prints the following:

D:\> java UnCheckedExceptionExample2

Error: No arguments passed in the commandline!

Pass the name of the file to open as commandline argument

Yes, showing the error message and telling the user the right thing to do is good. However, this approach of catching a runtime exception such as ArrayIndexOutOfBoundsException is a bad practice! Why? Runtime exceptions such as ArrayIndexOutOfBoundsException indicate likely programming errors, and you should fix the code instead of catching and handling the exceptions. So, how do you fix the program here? You can check the length of args before attempting to access the array member (see Listing 11-17).

Listing 11-17.  UnCheckedExceptionExample3.java

import java.io.*;

class UnCheckedExceptionExample3 {

        public static void main(String []args) throws FileNotFoundException {

                // if any argument is passed, it would be greater than or equal to one

                if(args.length >= 1) {

                        FileInputStream fis = new FileInputStream(args[0]);

                } else {

System.out.println("Error: No arguments passed in the commandline!"); System.out.println("Pass the name of the file to open as commandline argument");

                }

        }

}

The output is the same if no argument is passed to the program, but the code is better: it checks if it is possible to perform array indexing before actually indexing the array and thus is programmed defensively. 

It is a good practice to perform defensive checks and avoid raising unnecessary runtime exceptions.

Table 11-2 summarizes the important subclasses of the RuntimeException class.

340

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]