Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Intro_Java_brief_Liang2011.pdf
Скачиваний:
194
Добавлен:
26.03.2016
Размер:
10.44 Mб
Скачать

432Chapter 13 Exception Handling

13.1Introduction

Runtime errors occur while a program is running if the environment detects an operation that is impossible to carry out. For example, if you access an array using an index out of bounds, your program will get a runtime error with an ArrayIndexOutOfBoundsException. To read data from a file, you need to create a Scanner object using new Scanner(new File(filename)) (see Listing 9.6). If the file does not exist, your program will get a runtime error with a FileNotFoundException.

In Java, runtime errors are caused by exceptions. An exception is an object that represents an error or a condition that prevents execution from proceeding normally. If the exception is not handled, the program will terminate abnormally. How can you handle the exception so that the program can continue to run or else terminate gracefully? This is the subject we introduce in this chapter.

Video Note

Exception-handling advantages

reads two integers

integer division

13.2 Exception-Handling Overview

To demonstrate exception handling, including how an exception object is created and thrown, we begin with an example (Listing 13.1) that reads in two integers and displays their quotient.

LISTING 13.1 Quotient.java

1 import java.util.Scanner;

2

3 public class Quotient {

4 public static void main(String[] args) {

5 Scanner input = new Scanner(System.in);

6

7 // Prompt the user to enter two integers

8 System.out.print("Enter two integers: ");

9 int number1 = input.nextInt();

10 int number2 = input.nextInt();

11

12System.out.println(number1 + " / " + number2 + " is " +

13(number1 / number2));

14}

15}

Enter two integers: 5 2 5 / 2 is 2

Enter two integers: 3 0

Exception in thread "main" java.lang.ArithmeticException: / by zero at Quotient.main(Quotient.java:11)

If you entered 0 for the second number, a runtime error would occur, because you cannot divide an integer by 0. (Recall that a floating-point number divided by 0 does not raise an exception.) A simple way to fix the error is to add an if statement to test the second number, as shown in Listing 13.2.

LISTING 13.2 QuotientWithIf.java

1 import java.util.Scanner;

2

3 public class QuotientWithIf {

13.2 Exception-Handling Overview 433

4 public static void main(String[] args) {

5 Scanner input = new Scanner(System.in);

6

7 // Prompt the user to enter two integers

8System.out.print("Enter two integers: ");

9

int number1 = input.nextInt();

reads two integers

10

int number2 = input.nextInt();

 

11

 

 

12

if (number2 != 0)

test number2

13System.out.println(number1 + " / " + number2

14+ " is " + (number1 / number2));

15else

16System.out.println("Divisor cannot be zero ");

17}

18}

Enter two integers: 5 0

Divisor cannot be zero

In order to demonstrate the concept of exception handling, including how to create, throw, catch, and handle an exception, we rewrite Listing 13.2 as shown in Listing 13.3.

LISTING 13.3 QuotientWithException.java

1 import java.util.Scanner;

2

3 public class QuotientWithException {

4 public static void main(String[] args) {

5 Scanner input = new Scanner(System.in);

6

7 // Prompt the user to enter two integers

8System.out.print("Enter two integers: ");

9

int number1 = input.nextInt();

reads two integers

10

int number2 = input.nextInt();

 

11

 

 

 

 

12

 

try {

 

try block

13if (number2 == 0)

14throw new ArithmeticException("Divisor cannot be zero");

15

16System.out.println(number1 + " / " + number2 + " is " +

17(number1 / number2));

18}

19

catch (ArithmeticException ex) {

catch block

20System.out.println("Exception: an integer " +

21"cannot be divided by zero ");

22}

23

24System.out.println("Execution continues ...");

25}

26}

Enter two integers: 5 3 5 / 3 is 1

Execution continues ...

434 Chapter 13 Exception Handling

Enter two integers: 5 0

Exception: an integer cannot be divided by zero

Execution continues ...

 

The program contains a try block and a catch block. The try block (lines 12–18) contains

 

the code that is executed in normal circumstances. The catch block (lines 19–22) contains

 

the code that is executed when number2 is 0. In this event the program throws an exception

 

by executing

throw statement

throw new ArithmeticException("Divisor cannot be zero");

 

The value thrown, in this case new ArithmeticException("Divisor cannot be

exception

zero"), is called an exception. The execution of a throw statement is called throwing an

throwing exception

exception. The exception is an object created from an exception class. In this case, the excep-

 

tion class is java.lang.ArithmeticException.

 

When an exception is thrown, the normal execution flow is interrupted. As the name sug-

 

gests, to “throw an exception” is to pass the exception from one place to another. The excep-

handle exception

tion is caught by the catch block. The code in the catch block is executed to handle the

 

exception. Afterward, the statement (line 24) after the catch block is executed.

 

The throw statement is analogous to a method call, but instead of calling a method, it calls

 

a catch block. In this sense, a catch block is like a method definition with a parameter that

 

matches the type of the value being thrown. Unlike a method, after the catch block is exe-

 

cuted, however, the program control does not return to the throw statement; instead, it exe-

 

cutes the next statement after the catch block.

 

The identifier ex in the catch–block header

 

catch (ArithmeticException ex)

 

acts very much like a parameter in a method. So this parameter is referred to as a

catch–block parameter

catch–block parameter. The type (e.g., ArithmeticException) preceding ex specifies

 

what kind of exception the catch block can catch. Once the exception is caught, you can

 

access the thrown value from this parameter in the body of a catch block.

 

In summary, a template for a try-throw-catch block may look like this:

 

try {

Code to try;

Throw an exception with a throw statement or from method if necessary;

More code to try;

}

catch (type ex) {

Code to process the exception;

}

An exception may be thrown directly by using a throw statement in a try block, or by invoking a method that may throw an exception.

13.3 Exception-Handling Advantages

You have seen from Listing 13.3 how an exception is created, thrown, caught, and handled. You may wonder what the benefits are. To see these benefits, we rewrite Listing 13.3 to compute a quotient using a method, as shown in Listing 13.4.

13.3 Exception-Handling Advantages 435

LISTING 13.4 QuotientWithMethod.java

1

import java.util.Scanner;

 

2

 

 

 

3

public class QuotientWithMethod {

 

4

 

public static int quotient(int number1, int number2) {

quotient method

5if (number2 == 0)

6

 

throw new ArithmeticException("Divisor cannot be zero");

throw exception

7

 

 

 

8

return number1 / number2;

 

9

}

 

 

10

 

 

 

11public static void main(String[] args) {

12Scanner input = new Scanner(System.in);

14// Prompt the user to enter two integers

15System.out.print("Enter two integers: ");

16

 

int

number1 = input.nextInt();

reads two integers

17

 

int

number2 = input.nextInt();

 

18

 

 

 

 

 

 

 

 

 

 

19

 

try

{

 

 

 

try block

20

 

 

 

 

int result = quotient(number1, number2);

 

invoke method

If an

 

 

 

 

21

Arithmetic System.out.println(number1 + " / " + number2 + " is "

 

22

Exception

+ result);

 

23

occurs

}

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

24

 

catch (ArithmeticException ex) {

 

 

catch block

25

 

 

 

 

System.out.println("Exception: an integer " +

 

 

 

 

 

 

26"cannot be divided by zero ");

27}

28

29System.out.println("Execution continues ...");

30}

31}

Enter two integers: 5 3 5 / 3 is 1

Execution continues ...

Enter two integers: 5 0

Exception: an integer cannot be divided by zero

Execution continues ...

Method quotient (lines 4–9) returns the quotient of two integers. If number2 is 0, it cannot return a value. So, an exception is thrown in line 6.

The main method invokes quotient (line 20). If the quotient method executes normally, it returns a value to the caller. If the quotient method encounters an exception, it throws the exception back to its caller. The caller’s catch block handles the exception.

Now you see the advantages of using exception handling. It enables a method to throw an advantage exception to its caller. The caller can handle this exception. Without this capability, the called

method itself must handle the exception or terminate the program. Often the called method does not know what to do in case of error. This is typically the case for the library methods. The library method can detect the error, but only the caller knows what needs to be done when

436 Chapter 13 Exception Handling

an error occurs. The essential benefit of exception handling is to separate the detection of an error (done in a called method) from the handling of an error (done in the calling method).

Many library methods throw exceptions. Listing 13.5 gives an example that handles

FileNotFoundException for invoking the Scanner(File file) constructor.

LISTING 13.5 FileNotFoundExceptionDemo.java

 

1

import java.util.Scanner;

 

2

import java.io.*;

 

3

 

 

 

 

 

 

 

 

 

4

public class FileNotFoundExceptionDemo {

 

5

public static void main(String[] args) {

 

6

 

Scanner inputFromConsole = new Scanner(System.in);

 

7

 

// Prompt the user to enter a file name

 

8

 

System.out.print("Enter a file name: ");

 

9

 

String filename = inputFromConsole.nextLine();

 

10

 

 

 

 

 

 

 

 

try block

11

 

try {

 

create a Scanner

12

 

 

 

 

Scanner inputFromFile = new Scanner(new File(filename));

 

If a

 

 

 

 

 

13

FileNot- System.out.println("File " + filename + " exists ");

 

14

Found

 

 

 

// Processing file ...

 

15

Exception

 

 

 

 

 

occurs

}

 

 

 

 

 

catch block

16

 

catch (FileNotFoundException ex) {

 

 

 

17

 

 

 

 

System.out.println("Exception: " + filename + " not found");

 

 

 

 

 

 

18

 

}

 

 

 

 

 

 

19

}

 

 

 

 

 

 

 

 

20

}

 

 

 

 

 

 

 

Enter a file name: c:\book\Welcome.java

File c:\book\Welcome.java exists

Enter a file name: c:\book\Test10.java

Exception: c:\book\Test10.java not found

The program creates a Scanner for a file (line 12). If the file does not exist, the constructor throws a FileNotFoundException, which is caught in the catch block.

Listing 13.6 gives an example that handles an InputMismatchException exception.

LISTING 13.6 InputMismatchExceptionDemo.java

 

1

import java.util.*;

 

2

 

 

 

 

 

 

 

3

public class InputMismatchExceptionDemo {

 

4

public static void main(String[] args) {

 

5

Scanner input = new Scanner(System.in);

 

6

boolean continueInput = true;

 

7

 

 

 

 

 

 

 

8

do {

 

 

 

 

9

 

try

{

 

10

 

 

 

System.out.print("Enter an integer: ");

try block

11

 

 

int number = input.nextInt();

 

If an InputMi

 

create a Scanner

 

 

 

12

smatchExcep-

 

 

 

 

13

tion occurs

// Display the result

 

14

 

 

 

System.out.println(

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