chapter 15 - exception handling using try and catch blocks to handle "dangerous" method...

45
Chapter 15 - Exception Handling Using try and catch Blocks to Handle "Dangerous" Method Calls NumberFormatException Line Plot Example try and catch Blocks - More Details Two Types of Exceptions - Checked and Unchecked Unchecked Exceptions Checked Exceptions Using API Documentation when Writing Exception-Handling Code When a try Block Throws Different Types of Exceptions Generic catch Block With Exception Class Multiple catch Blocks and Multiple Exceptions Per Block Understanding Exception Messages Using throws to Postpone the catch Automatic Cleanup with Try-With-Resources 1

Upload: jodie-lilian-allen

Post on 18-Jan-2016

222 views

Category:

Documents


4 download

TRANSCRIPT

Page 1: Chapter 15 - Exception Handling Using try and catch Blocks to Handle "Dangerous" Method Calls NumberFormatException Line Plot Example try and catch Blocks

Chapter 15 - Exception Handling

Using try and catch Blocks to Handle "Dangerous" Method Calls NumberFormatException Line Plot Example try and catch Blocks - More Details Two Types of Exceptions - Checked and Unchecked Unchecked Exceptions Checked Exceptions Using API Documentation when Writing Exception-Handling Code When a try Block Throws Different Types of Exceptions Generic catch Block With Exception Class Multiple catch Blocks and Multiple Exceptions Per Block Understanding Exception Messages Using throws to Postpone the catch Automatic Cleanup with Try-With-Resources

1

Page 2: Chapter 15 - Exception Handling Using try and catch Blocks to Handle "Dangerous" Method Calls NumberFormatException Line Plot Example try and catch Blocks

Using try and catch Blocks to Handle "Dangerous" Method Calls

Some API method calls are "dangerous" in that they might possibly lead to a runtime error.

Example of a "safe" API method call (no runtime error possible):System.out.println(<expression>)

Example of an API method call that might lead to a runtime error:Integer.parseInt(<string>)

Technique for handling such runtime errors: Use exception handling. More specifically, surround

the method call with a try block and insert a catch block immediately after the try block.

2

Page 3: Chapter 15 - Exception Handling Using try and catch Blocks to Handle "Dangerous" Method Calls NumberFormatException Line Plot Example try and catch Blocks

Using try and catch Blocks to Handle "Dangerous" Method Calls

Syntax for try and catch blocks:try{ <statement(s)>}catch (<exception-class> <parameter>){ <error-handling-code>}

Example try and catch code fragment:try{ quantity = Integer.parseInt(userEntry);}catch (NumberFormatException nfe){ System.out.println("Invalid quantity entered." + " Must be a whole number.");}

Normally, one or more of these statements will be a "dangerous" API method call or constructor call.

The exception class should match the type of exception that the try block might throw.

3

Page 4: Chapter 15 - Exception Handling Using try and catch Blocks to Handle "Dangerous" Method Calls NumberFormatException Line Plot Example try and catch Blocks

Using try and catch Blocks to Handle "Dangerous" Method Calls

Semantics for previous slide's try and catch code fragment:

If the userEntry string contains all digits, then: The int version of userEntry is assigned into quantity.

The JVM skips the catch block and continues below it. If the userEntry string does not contain all digits,

then: The parseInt method throws a NumberFormatException object.

The JVM looks for a catch block that will catch the thrown exception object; that is, it looks for a matching catch block. If it finds one, it executes it and continues below the catch block. If there's no matching catch block, the program crashes.

4

Page 5: Chapter 15 - Exception Handling Using try and catch Blocks to Handle "Dangerous" Method Calls NumberFormatException Line Plot Example try and catch Blocks

NumberFormatException

The NumberFormatException is well named because it's thrown when a number's format is inappropriate.

More specifically, it's thrown by one of the parse methods (Integer.parseInt, Long.parseLong, Double.parseDouble, etc.) when there's an attempt to convert a string to a number and the string's characters don't form a valid number.

These code fragments throw NumberFormatExceptions:int numOfPages = Integer.parseInt("962.0");double height = Double.parseDouble("1.76m");

5

Page 6: Chapter 15 - Exception Handling Using try and catch Blocks to Handle "Dangerous" Method Calls NumberFormatException Line Plot Example try and catch Blocks

Line Plot Example This program plots a line by reading in a series of point coordinate positions.

It works fine as long as the user enters valid input. But with invalid input, the program crashes. Add code so as to avoid those crashes.

import java.util.Scanner;

public class LinePlot{ private int oldX = 0; // oldX, oldY save the previous point private int oldY = 0; // The starting point is the origin (0,0)

//*************************************************************

// This method prints a line segment from the previous point // to the current point.

public void plotSegment(int x, int y) { System.out.println("New segment = (" + oldX + "," + oldY + ")-(" + x + "," + y + ")"); oldX = x; oldY = y; } // end plotSegment

6

Page 7: Chapter 15 - Exception Handling Using try and catch Blocks to Handle "Dangerous" Method Calls NumberFormatException Line Plot Example try and catch Blocks

Line Plot Example

//*************************************************************

public static void main(String[] args) { Scanner stdIn = new Scanner(System.in); LinePlot line = new LinePlot(); String xStr, yStr; // coordinates for a point (String form) int x, y; // coordinates for a point

System.out.print("Enter x & y coordinates (q to quit): "); xStr = stdIn.next(); while (!xStr.equalsIgnoreCase("q")) { yStr = stdIn.next(); x = Integer.parseInt(xStr); y = Integer.parseInt(yStr); line.plotSegment(x, y); System.out.print("Enter x & y coordinates (q to quit): "); xStr = stdIn.next(); } // end while } // end main} // end class LinePlot

reads a group of characters and stops at whitespace

7

Page 8: Chapter 15 - Exception Handling Using try and catch Blocks to Handle "Dangerous" Method Calls NumberFormatException Line Plot Example try and catch Blocks

try and catch Blocks - More Details

Deciding on the size of your try blocks is a bit of an art. Sometimes it's better to use small try blocks and sometimes it's better to use larger try blocks.

Note that it's legal to surround an entire method body with a try block, but that's usually counterproductive because it makes it harder to identify the "dangerous" code.

In general, you should make your try blocks small so that your "dangerous" code is more obvious.

However, if a chunk of code has several "dangerous" method/constructor calls:

Adding a separate try-catch structure for each such call might result in cluttered code.

To improve program readability, consider using a single try block that surrounds the calls.

9

Page 9: Chapter 15 - Exception Handling Using try and catch Blocks to Handle "Dangerous" Method Calls NumberFormatException Line Plot Example try and catch Blocks

try and catch Blocks - More Details

In our LinePlot program solution, we surrounded the two parseInt statements with a single try block because they were conceptually related and physically close together. We also included the line.plotSegment() call within that same try block. Why?

Our single try block solution is perfectly acceptable, but wouldn't it be nice to have a more specific message that identified which entry was invalid (x, y, or both)?.

To have that sort of message, you'd have to have a separate try-catch structure for each parseInt statement.

10

Page 10: Chapter 15 - Exception Handling Using try and catch Blocks to Handle "Dangerous" Method Calls NumberFormatException Line Plot Example try and catch Blocks

try and catch Blocks - More Details

If an exception is thrown, the JVM immediately jumps out of the current try block and looks for a matching catch block. The immediacy of the jump means that if there are statements in the try block after the exception-throwing statement, those statements are skipped.

The compiler is a pessimist. It knows that statements inside a try block might possibly be skipped, and it assumes the worst. It assumes that all statements inside a try block get skipped.

Consequently, if there's a try block that contains an assignment for x, the compiler assumes that the assignment is skipped. If there's no assignment for x outside of the try block and x's value is needed outside of the try block, you'd get this compilation error:variable x might not have been initialized

If you get that error, you can usually fix it by initializing the variable prior to the try block.

11

Page 11: Chapter 15 - Exception Handling Using try and catch Blocks to Handle "Dangerous" Method Calls NumberFormatException Line Plot Example try and catch Blocks

try and catch Blocks - More Details

This method reads a value from a user, makes sure it's an integer, and returns it. Note the compilation errors. What are the fixes?

public static int getIntFromUser(){ Scanner stdIn = new Scanner(System.in); String xStr; // user entry boolean valid; // is user entry a valid integer? int x; // integer form of user entry

System.out.print("Enter an integer: "); xStr = stdIn.next(); do { try { valid = false; x = Integer.parseInt(xStr); valid = true; } catch (NumberFormatException nfe) { System.out.print("Invalid entry. Enter an integer: "); xStr = stdIn.next(); } } while (!valid);

return x;} // end getIntFromUser

compilation error: variable valid might not have been initializedcompilation error: variable x might not have been initialized

12

Page 12: Chapter 15 - Exception Handling Using try and catch Blocks to Handle "Dangerous" Method Calls NumberFormatException Line Plot Example try and catch Blocks

Two Types of Exceptions - Checked and Unchecked

There are two types of exceptions – checked and unchecked.

Checked exceptions are required to be checked with a try-catch mechanism.

Unchecked exceptions are not required to be checked with a try-catch mechanism (but, as an option, unchecked exceptions may be checked with a try-catch mechanism).

How can you tell whether a particular exception is classified as checked or unchecked?

To find out if a particular exception is checked or unchecked, look up its associated class in the API documentation.

On the class's API page, look at its class hierarchy tree. If you find that the class is derived from the RuntimeExeption class or from the Error exception class, then it's an unchecked exception. Otherwise, it's a checked exception.

13

Page 13: Chapter 15 - Exception Handling Using try and catch Blocks to Handle "Dangerous" Method Calls NumberFormatException Line Plot Example try and catch Blocks

Two Types of Exceptions - Checked and Unchecked

The parseInt, parseLong, parseDouble, etc. methods all throw a NumberFormatException object.

RuntimeException

Error Exception

Throwable

checked exceptions(e.g., IOException)

unchecked exceptions(e.g., NumberFormatException,

ArithmeticException)

unchecked exceptions forsystem errors (e.g.,

VirtualMachineError)

Class Hierarchy For Exception Classes

14

Page 14: Chapter 15 - Exception Handling Using try and catch Blocks to Handle "Dangerous" Method Calls NumberFormatException Line Plot Example try and catch Blocks

Unchecked Exceptions

As you know, unchecked exceptions are not required to be checked with a try-catch mechanism. However, at runtime, if an unchecked exception is thrown and not caught, then the program will crash (terminate ungracefully).

How to handle code that might throw an unchecked exception:

Use a try-catch mechanism (see prior GetIntFromUser example).

or Don't attempt to catch the exception, but write the

code carefully so as to avoid the possibility of the exception being thrown (see upcoming example).

15

Page 15: Chapter 15 - Exception Handling Using try and catch Blocks to Handle "Dangerous" Method Calls NumberFormatException Line Plot Example try and catch Blocks

Unchecked Exceptions

The following method attempts to remove a specified student from a list of student names. The list of student names is stored in an ArrayList instance variable named students.public void removeStudent(int index)

{

students.remove(index);

} // end removeStudent

The students.remove method call is dangerous because it throws an unchecked exception, IndexOutOfBoundsException, if its argument holds an invalid index.

On the upcoming slides, we address that problem by providing improved versions of the removeStudent method.

16

Page 16: Chapter 15 - Exception Handling Using try and catch Blocks to Handle "Dangerous" Method Calls NumberFormatException Line Plot Example try and catch Blocks

Unchecked Exceptions

Improved removeStudent method using a try-catch mechanism:

public void removeStudent(int index){ try { students.remove(index); } catch (IndexOutOfBoundsException e) { System.out.println( "Can't remove student because " + index + " is an invalid index position."); }} // end removeStudent

17

Page 17: Chapter 15 - Exception Handling Using try and catch Blocks to Handle "Dangerous" Method Calls NumberFormatException Line Plot Example try and catch Blocks

Unchecked Exceptions

Improved removeStudent method, using careful code:

public void removeStudent(int index){ if (index >= 0 && index < students.size()) { students.remove(index); } else { System.out.println( "Can't remove student because " + index + " is an invalid index position."); }} // end removeStudent

18

Page 18: Chapter 15 - Exception Handling Using try and catch Blocks to Handle "Dangerous" Method Calls NumberFormatException Line Plot Example try and catch Blocks

Checked Exceptions

If a code fragment has the potential of throwing a checked exception, then the compiler requires that the code fragment has an associated try-catch mechanism. If there is no associated try-catch mechanism, then the compiler generates an error.

The program on the next slide contains code that might possibly throw a checked exception and there's no try-catch mechanism. Thus, it generates a compilation error. What code should be added to fix the program?

19

Page 19: Chapter 15 - Exception Handling Using try and catch Blocks to Handle "Dangerous" Method Calls NumberFormatException Line Plot Example try and catch Blocks

/************************************************************** CreateTimestampFile.java* Dean & Dean** This program creates a file, using a timestamp for its name.*************************************************************/

import java.util.Date;import java.nio.file.*; // for Path, Paths, Files

public class CreateTimestampFile{ public static void main(String[] args) { String timestamp; // current date and time String filename; // use timestamp for this filename Path path; // file location timestamp = new Date().toString(); filename = timestamp.replaceAll(" ", "_").replaceAll(":", "_") + ".txt"; path = Paths.get(filename);

Files.createFile(path); System.out.println(filename + " created."); } // end main} // end CreateTimestampFile class

Checked Exceptions

unknown API constructor call

unknown API method calls

20

Page 20: Chapter 15 - Exception Handling Using try and catch Blocks to Handle "Dangerous" Method Calls NumberFormatException Line Plot Example try and catch Blocks

Using API Documentation when Writing Exception-Handling Code

Whenever you want to use a method or constructor from one of the API classes and you're not sure about it, you should look it up in the API documentation so you know whether to add exception-handling code.

More specifically, use the API documentation to figure out these things:

Can the method/constructor call possibly throw an exception?

On the API documentation page for the method/constructor, look for a throws section. If there's a throws section, that means the method/constructor can possibly throw an exception.

If the method/constructor call throws an exception, is it checked or unchecked?

On the API documentation page for the method/constructor, drill down on the exception class's name.

On the API documentation page for the exception class, look at the exception class's class hierarchy.

If you find RuntimeException is an ancestor of the exception, then the exception is an unchecked exception. Otherwise, it's a checked exception.

21

Page 21: Chapter 15 - Exception Handling Using try and catch Blocks to Handle "Dangerous" Method Calls NumberFormatException Line Plot Example try and catch Blocks

Using API Documentation when Writing Exception-Handling Code

If the method/constructor call can possibly throw a checked exception, you must add a try-catch mechanism to handle it.

If the method/constructor call can possibly throw an unchecked exception, you should read the API documentation to figure out the nature of the exception. And then, depending on the situation, 1) use a try-catch mechanism or 2) use careful code so that the exception won't be thrown.

22

Page 22: Chapter 15 - Exception Handling Using try and catch Blocks to Handle "Dangerous" Method Calls NumberFormatException Line Plot Example try and catch Blocks

Using API Documentation when Writing Exception-Handling Code

Handling the three "unknown" API method calls in the CreateTimestampFile Program:

new Date() Instantiates a Date object that holds the current time. No exceptions are thrown.

Paths.get(filename) Returns a Java Path object, which defines a file and its directory path. Throws an unchecked InvalidPathException if its filename

argument contains characters that are illegal in a filename and path. Files.createFile(path)

Creates a file stored in auxiliary memory. Throws a checked IOException if there's an I/O problem, like a

corrupt hard disk. Throws a checked FileAlreadyExistsException if there's an

attempt to create a file that already exists. Throws 2 unchecked exceptions - UnsupportedOperationException

and SecurityException, which can be ignored for this program.

23

Page 23: Chapter 15 - Exception Handling Using try and catch Blocks to Handle "Dangerous" Method Calls NumberFormatException Line Plot Example try and catch Blocks

import java.util.Date;import java.io.IOException;import java.nio.file.*; // for Path, Paths, Files

public class CreateTimestampFile{ public static void main(String[] args) { String timestamp; // current date and time String filename; // use timestamp for this filename Path path; // file location timestamp = new Date().toString(); filename = timestamp.replaceAll(" ", "_").replaceAll(":", "_") + ".txt"; path = Paths.get(filename);

try { Files.createFile(path); System.out.println(filename + " created."); } catch (IOException e) { System.out.println("File I/O error"); } } // end main} // end CreateTimestampFile class

Improved CreateTimestampFile Program

We need a try block for the 2 checked exceptions - IOException and FileAlreadyExistsException.

Since IOException is a superclass of FileAlreadyExistsException, we can use the single IOException parameter to catch both types of thrown exceptions.

24

Page 24: Chapter 15 - Exception Handling Using try and catch Blocks to Handle "Dangerous" Method Calls NumberFormatException Line Plot Example try and catch Blocks

When a try Block Throws Different Types of Exceptions

If several statements within a try block can possibly throw an exception and the exceptions are of different types, you should:

Provide a generic catch block that handles every type of exception that might be thrown.

or Provide a sequence of specific catch blocks, with

each catch block handling a different exception type or group of exception types.

25

Page 25: Chapter 15 - Exception Handling Using try and catch Blocks to Handle "Dangerous" Method Calls NumberFormatException Line Plot Example try and catch Blocks

How to provide a generic catch block: Define a catch block with an Exception parameter, e. Optionally, inside the catch block, use the e exception

object to call: getClass().getName(), which returns the class name of

the thrown exception object. getMessage(), which returns a description of the thrown

exception. For example:

catch (Exception e){ System.out.println(e.getClass().getName()); System.out.println(e.getMessage());}

Generic catch Block with Exception Class

26

Page 26: Chapter 15 - Exception Handling Using try and catch Blocks to Handle "Dangerous" Method Calls NumberFormatException Line Plot Example try and catch Blocks

In a catch block heading, if you use an Exception parameter, then all thrown exceptions will match up with the Exception parameter. Why?

A thrown exception will be caught by a catch block if the thrown exception's class equals the catch heading's parameter's class or the thrown exception's class is a subclass of the catch heading's parameter's class.

Since every thrown exception's class is a subclass of the Exception class, all thrown exceptions will match up with a generic Exception parameter.

The ReadFromFile program (on the next slide) illustrates how to use a generic catch block to handle multiple types of thrown exceptions.

The program opens a user-specified file and prints all the lines in that file.

Generic catch Block with Exception Class

27

Page 27: Chapter 15 - Exception Handling Using try and catch Blocks to Handle "Dangerous" Method Calls NumberFormatException Line Plot Example try and catch Blocks

/************************************************************ ReadFromFile.java* Dean & Dean** This opens an existing text file and prints its lines.***********************************************************/ import java.util.Scanner;import java.nio.file.Paths; public class ReadFromFile{ public static void main(String[] args) { Scanner stdIn = new Scanner(System.in); Scanner fileIn; // file handler String filename; // user-specified file name String line; // line of text

Generic catch Block with Exception Class

28

Page 28: Chapter 15 - Exception Handling Using try and catch Blocks to Handle "Dangerous" Method Calls NumberFormatException Line Plot Example try and catch Blocks

System.out.print("Enter a filename: "); try { filename = stdIn.nextLine(); fileIn = new Scanner(Paths.get(filename)); while (fileIn.hasNext()) { line = fileIn.nextLine(); System.out.println(line); } } // end try catch (Exception e) { System.out.println( "Thrown exception: " + e.getClass().getName()); System.out.println( "Exception message: " + e.getMessage()); } } // end main} // end ReadFromFile class

Generic catch Block with Exception Class

This Scanner constructor throws a checked exception.

This Scanner constructor throws a checked exception.

29

Page 29: Chapter 15 - Exception Handling Using try and catch Blocks to Handle "Dangerous" Method Calls NumberFormatException Line Plot Example try and catch Blocks

Sample session #1:Enter a filename: Einstein.*Thrown exception: java.nio.file.InvalidPathExceptionException message: Illegal char <*> at index 9: Einstein.*

Sample session #2:Enter a filename: EinsteinThrown exception: java.nio.file.NoSuchFileExceptionException message: Einstein

Sample session #3:Enter a filename: Einstein.txtA scientific theory should be as simple as possible,but not simpler.

Generic catch Block with Exception Class

30

Page 30: Chapter 15 - Exception Handling Using try and catch Blocks to Handle "Dangerous" Method Calls NumberFormatException Line Plot Example try and catch Blocks

The ReadFromFile program contains quite a few operations that can potentially throw an exception:

Paths.get throws an InvalidPathException (an unchecked exception).

The Scanner constructor throws an IOException (a checked exception).

hasNext throws IllegalStateException (an unchecked exception). nextLine throws IllegalStateException and

NoSuchElementException (both unchecked exceptions).

The program handles all of the exceptions above (checked and unchecked) with a generic catch block and its getClass().getName() and getMessage() method calls.

Generic catch Block with Exception Class

31

Page 31: Chapter 15 - Exception Handling Using try and catch Blocks to Handle "Dangerous" Method Calls NumberFormatException Line Plot Example try and catch Blocks

Multiple catch Blocks and Multiple Exceptions Per Block

When a try block might throw more than one type of exception, instead of providing one generic catch block, you can provide a sequence of catch blocks, with each catch block handling a different exception type or group of exception types.

For example: catch (InvalidPathException | NoSuchFileException e) { System.out.println("Filename invalid or not found."); } // end catching exceptions user can handle catch (Exception e) { System.out.println(e.getClass() + ":"); System.out.println(e.getMessage()); }

What is a benefit of using multiple catch blocks rather than a single generic catch block?

32

Page 32: Chapter 15 - Exception Handling Using try and catch Blocks to Handle "Dangerous" Method Calls NumberFormatException Line Plot Example try and catch Blocks

/************************************************************** ReadFromFile2.java* Dean & Dean** This opens an existing text file and prints its lines.*************************************************************/ import java.util.Scanner;import java.nio.file.*; // Paths, specific exceptions public class ReadFromFile2{ public static void main(String[] args) { Scanner stdIn = new Scanner(System.in); Scanner fileIn; // file handler boolean validUserEntry = false;

do { System.out.print("Enter a filename: ");

Multiple catch Blocks and Multiple Exceptions Per Block

33

Page 33: Chapter 15 - Exception Handling Using try and catch Blocks to Handle "Dangerous" Method Calls NumberFormatException Line Plot Example try and catch Blocks

try { fileIn = new Scanner(Paths.get(stdIn.nextLine())); // Above statement succeeds only when valid user input validUserEntry = true; while (fileIn.hasNext()) { System.out.println(fileIn.nextLine()); } } // end try catch (InvalidPathException | NoSuchFileException e) { System.out.println("Filename invalid or not found."); } // end catching exceptions user can handle catch (Exception e) { System.out.println(e.getClass() + ":"); System.out.println(e.getMessage()); } } while (!validUserEntry); } // end main} // end ReadFromFile2 class

Multiple catch Blocks and Multiple Exceptions Per Block

Rules for multiple exceptions in a catch block heading:1.Use a single vertical bar to separate the parameters.2.The exception parameters must not be in the same class hierarchy tree.

Rules for multiple exceptions in a catch block heading:1.Use a single vertical bar to separate the parameters.2.The exception parameters must not be in the same class hierarchy tree.

34

Page 34: Chapter 15 - Exception Handling Using try and catch Blocks to Handle "Dangerous" Method Calls NumberFormatException Line Plot Example try and catch Blocks

Multiple catch Block Execution Sequence

If multiple catch blocks are used, the first catch block that matches the type of the exception thrown is the one that is executed; the other catch blocks are then skipped.

Whenever you use more than one catch block after a given try block, and one catch block's exception class is derived from another catch block's exception class, to avoid a compilation error, you must arrange the catch blocks with the more general exception classes at the bottom (the superclasses go at the bottom).

For example, in the prior ReadFromFile2 program, you must put the Exception catch block at the bottom because the Exception class is a superclass of the InvalidPathException and NoSuchFileException classes.

35

Page 35: Chapter 15 - Exception Handling Using try and catch Blocks to Handle "Dangerous" Method Calls NumberFormatException Line Plot Example try and catch Blocks

Multiple catch Block Development

The original ReadFromFile program shows how you can use the compiler’s knowledge and experiment with a simple generic catch block to discover the types of exceptions that might be thrown by various forms of bad input.

Once you have discovered all the types of exceptions that bad user entries might generate, you can put these particular exceptions into additional catch block(s) inserted before the generic catch block.

Then, modify the code so that if a bad entry occurs, the program prints a short error message, repeats the original prompt, and prompts for new input.

36

Page 36: Chapter 15 - Exception Handling Using try and catch Blocks to Handle "Dangerous" Method Calls NumberFormatException Line Plot Example try and catch Blocks

Understanding Exception Messages

As you know, if your code involves a checked exception being thrown, you must include a try-catch mechanism for that code. Without the try-catch mechanism, your program won't compile successfully.

On the other hand, if your code involves an unchecked exception being thrown, it's optional whether you include a try-catch mechanism for that code. Without it, your program will compile successfully, but if an exception is thrown, your program will crash.

If such a crash occurs, the JVM prints a runtime error message that describes the thrown exception.

37

Page 37: Chapter 15 - Exception Handling Using try and catch Blocks to Handle "Dangerous" Method Calls NumberFormatException Line Plot Example try and catch Blocks

Understanding Exception Messages

import java.util.Scanner;

public class NumberList{ private int[] numList = new int[100]; // array of numbers private int size = 0; // number of numbers

//***************************************

public void readNumbers() { Scanner stdIn = new Scanner(System.in); String xStr; // user-entered number (String form) int x; // user-entered number

System.out.print("Enter a whole number (q to quit): "); xStr = stdIn.next();

while (!xStr.equalsIgnoreCase("q")) { x = Integer.parseInt(xStr); numList[size] = x; size++; System.out.print("Enter a whole number (q to quit): ");

38

Page 38: Chapter 15 - Exception Handling Using try and catch Blocks to Handle "Dangerous" Method Calls NumberFormatException Line Plot Example try and catch Blocks

Understanding Exception Messages

xStr = stdIn.next(); } // end while } // end readNumbers

//***************************************

public double getMean() { int sum = 0; for (int i=0; i<size; i++) { sum += numList[i]; } return sum / size; } // end getMean

//***************************************

public static void main(String[] args) { NumberList list = new NumberList(); list.readNumbers(); System.out.println("Mean = " + list.getMean()); } // end main} // end class NumberList

39

Page 39: Chapter 15 - Exception Handling Using try and catch Blocks to Handle "Dangerous" Method Calls NumberFormatException Line Plot Example try and catch Blocks

Understanding Exception Messages

The NumberList program compiles and runs, but it's not very robust. See below:

If this happens: Approximate error message:

User enters a non-integer (e.g., hi).

Exception in thread "main" java.lang.NumberFormatException: For input string: "hi"

at java.lang.Integer.parseInt(Integer.java:468)

at NumberList.readNumbers(NumberList.java:28)

at NumberList.main(NumberList.java:73)

User immediately enters q to quit.

Exception in thread "main" java.lang.ArithmeticException:

/ by zero

at NumberList.getMean(NumberList.java:49)

at NumberList.main(NumberList.java:58)

User enters more than 100 numbers.

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

at NumberList.readNumbers(NumberList.java:29)

at NumberList.main(NumberList.java:73)

call-stack trace

thrown exception

40

Page 40: Chapter 15 - Exception Handling Using try and catch Blocks to Handle "Dangerous" Method Calls NumberFormatException Line Plot Example try and catch Blocks

Understanding Exception Messages

As part of a runtime error, the JVM prints the exception that was thrown and then prints the call-stack trace. The call-stack trace shows the methods that were called prior to the crash.

If you perform integer division with a denominator of zero, the JVM throws an ArithmeticException object.

If you access an array element with an array index that's < 0 or >= the array's size, the JVM throws an ArrayIndexOutOfBoundsException object.

41

Page 41: Chapter 15 - Exception Handling Using try and catch Blocks to Handle "Dangerous" Method Calls NumberFormatException Line Plot Example try and catch Blocks

Using throws to Postpone the catch

Suppose you have a utility method that might throw an exception, but the original causes of that exception are in the calling methods.

Or suppose you have a non-void return method that sometimes throws an exception and that method’s exception handler cannot know what value to have the method return.

Then it’s appropriate to move the try and catch blocks from the called method back to the calling method(s). To do this, append throws <exception-type> to the called method’s header.

For example, suppose you want a variation of the previous removeStudent method to return the removed student’s name:

public String removeStudent(int index) throws IndexOutOfBoundsException{ return students.remove(index);} // end removeStudent

42

Page 42: Chapter 15 - Exception Handling Using try and catch Blocks to Handle "Dangerous" Method Calls NumberFormatException Line Plot Example try and catch Blocks

Using throws to Postpone the catch

Scanner stdIn = new Scanner(System.in); String[] names = {"Caleb", "Izumi", "Mary", "Usha"}; StudentList2 studentList = new StudentList2(names); int index; boolean reenter;

do { System.out.print("Enter index of student to remove: "); index = stdIn.nextInt(); try { System.out.println( "removed " + studentList.removeStudent(index)); reenter = false; } catch (IndexOutOfBoundsException e) { System.out.print("Invalid entry. "); reenter = true; } } while (reenter);

43

Page 43: Chapter 15 - Exception Handling Using try and catch Blocks to Handle "Dangerous" Method Calls NumberFormatException Line Plot Example try and catch Blocks

Cleanup With finally Block Sometimes you need to provide cleanup code that executes

regardless of whether an exception is thrown. For example, after writing to a file, you must close the file to complete the writing process. Closing also releases system resources and improves system performance.

Unfortunately, if some operation between file opening and file closing throws an exception, the close operation might be skipped.

The traditional way to deal with this is to put an explicit close method call in a separate finally block located immediately after the last catch block, like this:

finally{ if (fileOut != null){

fileOut.close(); }} // end finally

That’s ugly. Starting with Java 1.7, there’s a better way.

44

Page 44: Chapter 15 - Exception Handling Using try and catch Blocks to Handle "Dangerous" Method Calls NumberFormatException Line Plot Example try and catch Blocks

Automatic Cleanup Using Try-With-Resources

All classes that implement Closeable also implement AutoCloseable. When an object is AutoCloseable, instead of closing it with an explicit close statement, we can ask the JVM to close it for us by opening the AutoCloseable object with a try-with-resources header, like this:

/************************************************************** WriteToFile.java* Dean & Dean** This demonstrates a file writer using try-with-resources*************************************************************/

import java.io.*; // PrintWriter, IOException

public class WriteToFile{ public int write(String filename, String text) throws IOException { try (PrintWriter fileOut = new PrintWriter(filename)) { fileOut.println(text); return text.length(); // if exception is not thrown } // end try and close fileOut automatically } // end write

45

Page 45: Chapter 15 - Exception Handling Using try and catch Blocks to Handle "Dangerous" Method Calls NumberFormatException Line Plot Example try and catch Blocks

Automatic Cleanup Using Try-With-Resources

public static void main(String[] args) { String filename = "Feynman.txt"; String text = "It is fundamentally impossible to make " + "a precise prediction\n of exactly what will happen " + "in a given experiment."; int length = 0; WriteToFile writer = new WriteToFile();

try { length = writer.write(filename, text); System.out.println("written string length = " + length); } catch (Exception e) { System.out.println(e.getClass()); System.out.println(e.getMessage()); } } // end main} // end class WriteToFile

Sample session:written string length = 111

46