• No results found

Chapter 14 Exception Handling

N/A
N/A
Protected

Academic year: 2021

Share "Chapter 14 Exception Handling"

Copied!
41
0
0

Loading.... (view fulltext now)

Full text

(1)

Chapter 14

Exception Handling

(2)

Chapter Goals

• To learn how to throw exceptions

• To be able to design your own exception classes

• To understand the difference between checked and unchecked exceptions

• To learn how to catch exceptions

• To know when and where to catch an

(3)

Error Codes

• Traditional approach to error handling: method returns error code

• Example: JOptionPane.showInputDialog returns null if user hits Cancel

• Problem: Calling method may forget to check for error code

• Problem: Calling method may not know how to fix error--then it needs to return an error code

• Symptom: Programming for success

x.doSomething()

is replaced by programming for failure

if (!x.doSomething()) return false;

(4)

Exceptions

• Can't be overlooked

• Can be handled by a competent handler, not necessarily the calling method

• Throw an exception object to indicate failure

if (failure) {

   XxxException e = new XxxException(. . .);

   throw e;

}

• More concisely

(5)

Exceptions

public class BankAccount {

public void withdraw(double amount) {

if (amount > balance)

throw new IllegalArgumentException(

"Amount exceeds balance");

balance = balance - amount;

} ...

}

(6)

Hierarchy of Exception Classes

(7)

Syntax 14.1: Throwing an Exception

throw exceptionObject;

Example

:

 throw new IllegalArgumentException();

Purpose

:

To throw an exception and transfer control to a handler for this exception type

(8)

Checked Exceptions

• Compiler checks that you are aware of the exception

• Generally used for errors that can happen even in correct programs

IOException and its sublcasses are checked exceptions

NullPointerException, ArrayIndexOutOfBoundsException , ... are unchecked --they are your fault :-)

•Virtual machine errors (e.g. OutOfMemoryError) are unchecked

• Classification not perfect. For example, Integer.parseInt

throws unchecked NumberFormatException

(9)

Checked and Unchecked Exceptions

(10)

Exception Specifications

• BufferedReader.readLine may throw IOException

• Tag calling method with throws IOException public class Coin

{ public void read(BufferedReader in) throws IOException

{

value = Double.parseDouble(in.readLine());

name =in.readLine();

} ...

(11)

Exception Specifications

• Need to tag caller of Coin.read as well

• Stop at main or with handler (see below)

• Can have multiple exception types

public void read()

   throws IOException, ClassNotFoundException

• throws specifier not a sign of irresponsible programming

• Better to declare exception than to handle it incompetently

(12)

Syntax 14.2: Exception Specification

accessSpecifier returnType methodName (parameterType parameterName, . . .)

throws ExceptionClass, ExceptionClass . .

Example:

  public void read(BufferedReader in) throws IOException

Purpose:

To indicate the checked exceptions that a method can throw

(13)

Designing Your Own Exception Types

if (amount > balance)

   throw new InsufficientFundsException(. . .);

• Make it an unchecked exception--programmer could have avoided it by calling getBalance first

• Extend RuntimeException

• Supply two constructors

(14)

Designing Your Own Exception Types

public class InsufficientFundsException extends RuntimeException

{

public InsufficientFundsException() {

}  

public InsufficientFundsException(String reason) {

super(reason);

} }

(15)

Catching Exceptions

try {

BufferedReader in = new BufferedReader(

new InputStreamReader(System.in));

System.out.println("How old are you?");

String inputLine = in.readLine();

int age = Integer.parseInt(inputLine);

age++;

System.out.println("Next year,you'll be " + age);

}

catch (IOException exception) {

System.out.println("Input/output error “ +exception);

}

catch (NumberFormatException exception) {

System.out.println("Input was not a number");

}

(16)

Catching Exceptions

• Statements in try block are executed

• If no exceptions occur, catch clauses are skipped

• If exception of matching type occurs, execution jumps to catch clause

• If exception of another type occurs, it is thrown to the calling method

• If main doesn't catch an exception, the program

(17)

Syntax 14.3: General Try Block

try {

statement statement

...

}

catch (ExceptionClass exceptionObject) {

statement

statement ...

}

catch (ExceptionClass exceptionObject) {

statement statement

...

}

...

(18)

Example:

try {

System.out.println("What is your name?");

String name = console.readLine();

System.out.println("Hello,"+name +"!");

}

catch (IOException exception) {

exception.printStackTrace();

System.exit(1);

}

Purpose:

To execute one or more statements that may generate exceptions. If an exception of a particular type occurs, then stop executing those

statements and instead go to the matching catch clause. If no

(19)

The

finally

Clause

• Exception terminates current method

• Danger: Can skip over essential code

• Example:

BufferedReader in;

in = new BufferedReader(new FileReader(filename));

purse.read(in);

in.close(); 

• Must execute in.close() even if exception happens

• Use finally clause for code that must be executed

"no matter what"

(20)

The

finally

Clause

BufferedReader in = null;

try {

in = new BufferedReader(

new FileReader(filename));

purse.read(in);

} finally

{ if (in !=null) in.close();

(21)

The

finally

Clause

• Executed when

try

block comes to normal end

• Executed if a statement in

try

block throws an exception, before exception is thrown out of

try

block

• Can also be combined with

catch

clauses

(22)

Syntax 14.4: The

finally

Clause

 try {

   statement    statement    ...

}

finally {

    statement    statement

(23)

Example:

BufferedReader in = null;

try {

in = new BufferedReader(

new FileReader(filename));

purse.read(in);

}

Finally {

if (in !=null) in.close();

}

Purpose:

To execute one or more statements that may generate exceptions, and to execute the statements in the finally clause whether or not an exception occured.

(24)

A Complete Example

• Program

o reads coin descriptions from file o adds coins to purse

o prints total

• What can go wrong?

o File might not exist

o File might have data in wrong format

• Who can detect the faults?

o main method of PurseTest interacts with user

o main method can report errors

(25)

The

read

method of the

Coin

class

Distinguishes between expected and unexpected end of file

public boolean read(BufferedReader in) throws IOException

{

String input =in.readLine();

if (input == null) // normal end of file return false;

value = Double.parseDouble(input);

// may throw unchecked NumberFormatException name = in.readLine();

if (name == null) // unexpected end of file

throw new EOFException("Coin name expected");

return true;

}

(26)

The

read

method of the

Purse

class

• Unconcerned with exceptions

• Just passes them to caller

public void read(BufferedReader in) throws IOException

{

boolean done = false;

while (!done) {

Coin c = new Coin();

if (c.read(in)) add(c);

else done =true;

(27)

The

readFile

method of the

Purse

class

finally clause closes files if exception happens

public void readFile(String filename) throws IOException

{

BufferedReader in = null;

try {

in = new BufferedReader(

new FileReader(filename));

read(in);

}

finally {

if (in != null) in.close();

} }

(28)

User interaction in main

If an exception occurs, user can specify another file name

boolean done = false;

String filename =

JOptionPane.showInputDialog("Enter file name");

while (!done) {

try {

Purse myPurse = new Purse();

myPurse.readFile(filename);

System.out.println("total=" + myPurse.getTotal());

(29)

catch (IOException exception) {

System.out.println("Input/output error " + exception);

}

catch (NumberFormatException exception) {

exception.printStackTrace(); // error in file format

}

if (!done) {

Filename = JOptionPane.showInputDialog("Try another file:");

if (filename == null) done =true;

} }

(30)

Scenario

1. PurseTest.main calls Purse.readFile 2. Purse.readFile calls Purse.read

3. Purse.read calls Coin.read

4. Coin.read throws an EOFException

5. Coin.read has no handler for the exception and terminates immediately.

6. Purse.read has no handler for the exception and terminates immediately

7. Purse.readFile has no handler for the exception and terminates immediately after executing the finally clause and closing the file.

8. PurseTest.main has a handler for an IOException , a superclass of

EOFException. That handler prints a message to the user.

(31)

File PurseTest.java

1 import javax.swing.JOptionPane;

2 import java.io.IOException;

3 4 /**

5 This program prompts the user to enter a file name 6 with coin values. A purse object is filled with

7 the coins specified in the file. In case of an exception, 8 the user can choose another file.

9 */

10 public class PurseTest 11 {

12 public static void main(String[] args) 13 {

14 boolean done = false;

15 String filename

16 = JOptionPane.showInputDialog("Enter file name");

17

(32)

18 while (!done) 19 {

20 try 21 {

22 Purse myPurse = new Purse();

23 myPurse.readFile(filename);

24 System.out.println("total=" + myPurse.getTotal());

25 done = true;

26 }

27 catch (IOException exception) 28 {

29 System.out.println("Input/output error " + exception);

30 }

31 catch (NumberFormatException exception) 32 {

33 exception.printStackTrace();

34 } 35

36 if (!done) 37 {

(33)

38 filename = JOptionPane.showInputDialog(

39 "Try another file:");

40 if (filename == null) done = true;

41 } 42 }

43 System.exit(0);

44 } 45 }

(34)

File Purse.java

1 import java.io.BufferedReader;

2 import java.io.FileReader;

3 import java.io.IOException;

4 5 /**

6 A purse computes the total of a collection of coins.

7 */

8 public class Purse 9 {

10 /**

11 Constructs an empty purse.

12 */

13 public Purse() 14 {

15 total = 0;

16 } 17

(35)

18 /**

19 Read a file with coin descriptions and adds the coins 20 to the purse.

21 @param filename the name of the file 22 */

23 public void readFile(String filename) 24 throws IOException

25 {

26 BufferedReader in = null;

27 try 28 {

29 in = new BufferedReader(new FileReader(filename));

30 read(in);

31 } 32 finally 33 {

34 if (in != null) in.close();

35 } 36 } 37

(36)

38 /**

39 Read a file with coin descriptions and adds the coins 40 to the purse.

41 @param in the buffered reader for reading the input 42 */

43 public void read(BufferedReader in) 44 throws IOException

45 {

46 boolean done = false;

47 while (!done) 48 {

49 Coin c = new Coin();

50 if (c.read(in)) 51 add(c);

52 else

53 done = true;

54 } 55 } 56 57 /**

(37)

58 Add a coin to the purse.

59 @param aCoin the coin to add 60 */

61 public void add(Coin aCoin) 62 {

63 total = total + aCoin.getValue();

64 } 65 66 /**

67 Get the total value of the coins in the purse.

68 @return the sum of all coin values 69 */

70 public double getTotal() 71 {

72 return total;

73 } 74

75 private double total;

76 } 77

(38)

File Coin.java

1 import java.io.BufferedReader;

2 import java.io.EOFException;

3 import java.io.IOException;

4 5 /**

6 A coin with a monetary value.

7 */

8 public class Coin 9 {

10 /**

11 Constructs a default coin.

12 Use the read method to fill in the value and name.

13 */

14 public Coin() 15 {

16 value = 0;

17 name = "";

(39)

18 } 19 20 /**

21 Constructs a coin.

22 @param aValue the monetary value of the coin.

23 @param aName the name of the coin 24 */

25 public Coin(double aValue, String aName) 26 {

27 value = aValue;

28 name = aName;

29 } 30 31 /**

32 Reads a coin value and name.

33 @param in the reader

34 @return true if the data was read, 35 false if the end of the stream was reached 36 */

37 public boolean read(BufferedReader in)

(40)

38 throws IOException 39 {

40 String input = in.readLine();

41 if (input == null) return false;

42 value = Double.parseDouble(input);

43 name = in.readLine();

44 if (name == null)

45 throw new EOFException("Coin name expected");

46 return true;

47 } 48 49 /**

50 Gets the coin value.

51 @return the value 52 */

53 public double getValue() 54 {

55 return value;

56 } 57

(41)

58 /**

59 Gets the coin name.

60 @return the name 61 */

62 public String getName() 63 {

64 return name;

65 } 66

67 private double value;

68 private String name;

69 } 70 71 72 73 74 75 76 77 78

References

Related documents