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

Chapter 11 Exceptions and Assertions

When you run this program and type an integer, say 10, in the console, the program works correctly and prints the integer back to you successfully.

D:\> java ScanInt1

Type an integer in the console: 10

You typed the integer value: 10

However, what if you (or the user of the program) mistakenly type the string “ten” instead of the integer value “10”? The program will terminate after throwing an exception like this:

D:\> java ScanInt1

Type an integer in the console: ten

Exception in thread "main" java.util.InputMismatchException at java.util.Scanner.throwFor(Scanner.java:909)

at java.util.Scanner.next(Scanner.java:1530) at java.util.Scanner.nextInt(Scanner.java:2160) at java.util.Scanner.nextInt(Scanner.java:2119) at ScanInt.main(ScanInt1.java:7)

If you read the documentation of nextInt(), you’ll see that this method can throw InputMismatchException “ if the next token does not match the Integer regular expression, or is out of range.” In this simple program, you assume that you (or the user) will always type an integer value as expected, and when that assumption fails, an exception gets thrown. If there is an exception thrown from a program, and it is left unhandled, the program will terminate abnormally after throwing a stack trace like the ones shown here.

A stack trace shows the list of the method (with the line numbers) that was called before the control reached the statement where the exception was thrown. As a programmer, you’ll find it useful to trace the control flow for debugging the program and fix the problem that led to this exception.

So, how do you handle this situation? You need to put this code within try and catch blocks and then handle the exception.

Try and Catch Statements

Java provides the try and catch keywords to handle any exceptions that can get thrown in the code you write. Listing 11-3 is the improved version of the program from Listing 11-2.

Listing 11-3.  ScanInt2.java

//A simple progam to accept an integer from user in normal case,

//otherwise prints an error message

import java.util.*;

class ScanInt2 {

        public static void main(String [] args) {

                System.out.println("Type an integer in the console: ");

                Scanner consoleScanner = new Scanner(System.in);

                try {

         System.out.println("You typed the integer value: " + consoleScanner.nextInt());

         } catch(InputMismatchException ime) {

320

Chapter 11 Exceptions and Assertions

                         // nextInt() throws InputMismatchException in case anything other than an integer

                         // is typed in the console; so handle it System.out.println("Error: You typed some text that is not an integer value...");

                }

        }

}

If anything other than a valid integer is typed in the input, this program prints a readable error message to the user.

D:\> java ScanInt2

Type an integer in the console: ten

Error: You typed some text that is not an integer value...

Now let’s analyze this code. The block followed by the try keyword limits the code segment for which you expect that some exceptions could be thrown. If any exception gets thrown from the try block, the Java runtime will search for a matching handler (which we’ll discuss in more detail a bit later). In this case, an exception handler for InputMismatchException is present, which is of exactly the same type as the exception that got thrown. This exactly matching catch handler is available just outside the try block in the form of a block preceded by the keyword catch, and this catch block gets executed. In the catch block you caught the exception, so you’re handling the exception here. You are providing a human readable error string rather than throwing a raw stack trace (as you did in the earlier program in Listing 11-2), so you’re providing a graceful exit for the program.

Programmatically Accessing the Stack Trace

You saw that the stack trace is useful for debugging, so how to get it in the catch block? You can use the printStackTrace() method, which will print the stack trace to the console. Let’s add the following statement to the catch block:

ime.printStackTrace();

Now this statement will print the stack trace:

java.util.InputMismatchException

        at java.util.Scanner.throwFor(Scanner.java:909)

        at java.util.Scanner.next(Scanner.java:1530)

        at java.util.Scanner.nextInt(Scanner.java:2160)

        at java.util.Scanner.nextInt(Scanner.java:2119)

        at ScanInt2.main(ScanInt2.java:9)

You can also access each of the entries in the stack trace. All exceptions have a method named getStackTrace() that returns an array of StackTraceElements. So, consider that you write these statements in the catch block:

System.out.println("The calls in the stack trace are: ");

// access each element in the "call stack" and print them individually for(StackTraceElement methodCall : ime.getStackTrace())

System.out.println(methodCall);

321

Chapter 11 Exceptions and Assertions

When you execute this code segment, it will print the following:

The calls in the stack trace are: java.util.Scanner.throwFor(Scanner.java:909) java.util.Scanner.next(Scanner.java:1530) java.util.Scanner.nextInt(Scanner.java:2160) java.util.Scanner.nextInt(Scanner.java:2119) ScanInt2.main(ScanInt2.java:9)

Multiple Catch Blocks

In Listing 11-2, you used a Scanner object to read an integer from the console. Note that you can use a Scanner object to read from a String as well (see Listing 11-4).

Listing 11-4.  ScanInt3.java

// A program that scans an integer from a given string

import java.util.*;

class ScanInt3 {

public static void main(String [] args) {

                String integerStr = "100";

                System.out.println("The string to scan integer from it is: " + integerStr);

                Scanner consoleScanner = new Scanner(integerStr);

                try {

                        System.out.println("The integer value scanned from string is: " + consoleScanner.nextInt());

                } catch(InputMismatchException ime) {

                         // nextInt() throws InputMismatchException in case anything other than an integer

                        // is provided in the string

                        System.out.println("Error: Cannot scan an integer from the given string");

                }

}

}

This program prints the following:

The string to scan integer from it is: 100 The integer value scanned from string is: 100

What happens if you modify the program in Listing 11-4 so that the string contains a non-integer value, as in

String integerStr = "hundred";

The try block will throw an InputMismatchException, which will be handled in the catch block, and you’ll get this output:

The string to scan integer from it is: hundred

Error: Cannot scan an integer from the given string

322

Chapter 11 Exceptions and Assertions

Now, what if you modify the program in Listing 11-4 so that the string contains an empty string, as in

String integerStr = "";

For this, nextInt() will throw a NoSuchElementException, which is not handled in this program, so this program would crash.

The string to scan integer from it is:

Exception in thread "main" java.util.NoSuchElementException at java.util.Scanner.throwFor(Scanner.java:907)

at java.util.Scanner.next(Scanner.java:1530) at java.util.Scanner.nextInt(Scanner.java:2160) at java.util.Scanner.nextInt(Scanner.java:2119) at ScanInt3.main(ScanInt.java:11)

Further, if you look at the JavaDoc for Scanner.nextInt() method, you’ll find that it can also throw an IllegalStateException (this exception is thrown if the nextInt() method is called on a Scanner object that is already closed). So, let’s provide catch handlers for InputMismatchException, NoSuchElementException, and

IllegalStateException (see Listing 11-5).

Listing 11-5.  ScanInt4.java

// A program that scans an integer from a given string

import java.util.*;

class ScanInt4 {

        public static void main(String [] args) {

                String integerStr = "";

                System.out.println("The string to scan integer from it is: " + integerStr);

                Scanner consoleScanner = new Scanner(integerStr);

                try {

System.out.println("The integer value scanned from string is: " +

    consoleScanner.nextInt());

                } catch(InputMismatchException ime) {

                        System.out.println("Error: Cannot scan an integer from the given string");

                } catch(NoSuchElementException nsee) {

                        System.out.println("Error: Cannot scan an integer from the given string");

                } catch(IllegalStateException ise) {

                        System.out.println("Error: nextInt() called on a closed Scanner object");

                }

        }

}

Here is the output when you run this program:

The string to scan integer from it is:

Error: Cannot scan an integer from the given string

As you can see from the output, since the string is empty, NoSuchElementException gets thrown. It is caught in the catch handler for this exception, and the code provided inside the catch block gets executed to result in a graceful exit.

323

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