Java Exception Handling Exception an event that occurs

  • Slides: 32
Download presentation
Java Exception Handling ● Exception = an event that occurs during the execution of

Java Exception Handling ● Exception = an event that occurs during the execution of a program that disrupts the normal flow of instructions: – ● ● Examples: Hard disk crash; Out of bounds array access; Divide by zero, etc When an exception occurs, the executing method creates an Exception object and hands it to the runtime system--``throwing an exception'' The runtime system searches the runtime call stack for a method with an appropriate handler, which ``catches the exception''

Java's Exception Handling Policy ● ● Java is fussy about (some) exceptions, requiring that

Java's Exception Handling Policy ● ● Java is fussy about (some) exceptions, requiring that the programmer either: – deal with the exceptions when they occur, using try and catch, or – explicitly hand off the exception to the method that calls the method in which the exception occurs, effectively ``passing the buck'' to the calling method. The exceptions Java is fussy about are called ``checked'' exceptions, because the compiler will check that one of the above options is satisfied

Advantages of Java Exception Handling 1. Separating Error Handling Code from ``Regular'' Code 2.

Advantages of Java Exception Handling 1. Separating Error Handling Code from ``Regular'' Code 2. Propagating Errors Up the Call Stack 3. Grouping Error Types and Error Differentiation

Advantage 1: Separating Error Handling Code from ``Regular'' Code Example: Here is pseudocode for

Advantage 1: Separating Error Handling Code from ``Regular'' Code Example: Here is pseudocode for reading a file into memory: read. File { open the file; determine its size; allocate that much memory; read the file into memory; close the file; }

Problems with read. File ● ● ● What happens if the file can't be

Problems with read. File ● ● ● What happens if the file can't be opened? What happens if the length of the file can't be determined? What happens if enough memory can't be allocated? ● What happens if the read fails? ● What happens if the file can't be closed?

Error Handling With Traditional Programming error. Code. Type read. File { initialize error. Code

Error Handling With Traditional Programming error. Code. Type read. File { initialize error. Code = 0; open the file; if (the. File. Is. Open) { determine the length of the file; if (got. The. File. Length) { allocate that much memory; if (got. Enough. Memory) { read the file into memory; if (read. Failed) { error. Code = -1; } } else { error. Code = -2; } } else { error. Code = -3; } close the file; if (the. File. Didnt. Close && error. Code == 0) { error. Code = -4; } else { error. Code = error. Code and -4; } } else { error. Code = -5; } return error. Code;

Error Handling With Java read. File { try { open the file; determine its

Error Handling With Java read. File { try { open the file; determine its size; allocate that much memory; read the file into memory; close the file; } catch (file. Open. Failed) { do. Something; } catch (size. Determination. Failed) { do. Something; } catch (memory. Allocation. Failed) { do. Something; } catch (read. Failed) { do. Something; } catch (file. Close. Failed) { do. Something; } } Note that the error handling code and ``regular'' code are separate

Advantage 2: Propagating Errors Up the Call Stack method 1 { call method 2;

Advantage 2: Propagating Errors Up the Call Stack method 1 { call method 2; } method 2 { call method 3; } method 3 { call read. File; } read. File call method 3 method 2 method 1 Call Stack Suppose also that method 1 is the only method interested in the errors that occur within read. File. How does the error code get propogated up the stack?

Propagating Errors Using Traditional Programming method 1 { error. Code. Type error; error =

Propagating Errors Using Traditional Programming method 1 { error. Code. Type error; error = call method 2; if (error) do. Error. Processing; else proceed; } error. Code. Type method 2 { error. Code. Type error; error = call method 3; if (error) return error; else proceed; } error. Code. Type method 3 { error. Code. Type error; error = call read. File; if (error) return error; else proceed; } read. File call method 3 return method 2 method 1 Call Stack return

Propagating Errors Using Java method 1 { try { call method 2; } catch

Propagating Errors Using Java method 1 { try { call method 2; } catch (exception) { do. Error. Processing; } } method 2 throws exception { call method 3; } method 3 throws exception { call read. File; } read. File call method 3 method 2 method 1 Call Stack throw

Advantage 3: Grouping Error Types and Error Differentiation Java exceptions are first class Java

Advantage 3: Grouping Error Types and Error Differentiation Java exceptions are first class Java objects, and so they are grouped into a class hierarchy. For example: Exception Run. Time. Exception Null. Pointer. Exception Arithmetic. Exception IOException File. Not. Found. Exception Malformed. URLException

Example Suppose (remember, this is pseudocode): method 1 { try { call method 2;

Example Suppose (remember, this is pseudocode): method 1 { try { call method 2; } catch(Exception) { do. Error. Processing; } } method 2 throws Arithmetic. Exception {. . . call method 3; . . . } method 3 throws File. Not. Found. Exception {. . . call method 4; . . . } method 4 throws Null. Pointer. Exception {. . . }

Throwing Structure call method 4 method 3 method 2 throw method 1 Call Stack

Throwing Structure call method 4 method 3 method 2 throw method 1 Call Stack In this case, the exception handler in method 1 must handle all exception types

Modified Example method 1 { try { call method 2; } catch(Run. Time. Exception)

Modified Example method 1 { try { call method 2; } catch(Run. Time. Exception) { do. Error. Processing; } } method 2 throws Arithmetic. Exception {. . . call method 3; . . . } method 3 throws File. Not. Found. Exception {. . . call method 4; . . . } method 4 throws Null. Pointer. Exception {. . . }

New Throwing Structure call method 4 method 3 throw method 2 method 1 Call

New Throwing Structure call method 4 method 3 throw method 2 method 1 Call Stack In this case, method 1 will handle only runtime exceptions. Any File. Not. Found. Exception thrown by method 3 will have to be handled further down the stack.

Another Modified Example method 1 { try { call method 2; } catch(Run. Time.

Another Modified Example method 1 { try { call method 2; } catch(Run. Time. Exception) { do. Error. Processing; } } method 2 throws Arithmetic. Exception { try {. . . call method 3; . . . } catch(IOException) { do. More. Error. Processing; } } method 3 throws File. Not. Found. Exception {. . . call method 4; . . . } method 4 throws Null. Pointer. Exception {. . . }

New Throwing Structure call method 4 method 3 method 2 method 1 Call Stack

New Throwing Structure call method 4 method 3 method 2 method 1 Call Stack throw

File. Copy Example Revisited import java. io. *; public class File. Copy { public

File. Copy Example Revisited import java. io. *; public class File. Copy { public static void main(String[] args) throws IOException { Buffered. Reader br = new Buffered. Reader(new Input. Stream. Reader(System. in)); File. Reader r; File. Writer w; System. out. print("Source file name: "); String in. File. Name = br. read. Line(); r = new File. Reader(in. File. Name); System. out. print("Destination file name: "); String out. File. Name = br. read. Line(); w = new File. Writer(out. File. Name); int c; while ((c = r. read()) != -1) w. write(c); } w. flush();

If The Input File Does Not Exist In the example, the main method chooses

If The Input File Does Not Exist In the example, the main method chooses to ``pass the buck, '' but there is nowhere to pass it to. Thus, the program will crash: 4% java File. Copy Source file name: foo Exception in thread "main" java. io. File. Not. Found. Exception: foo (No such file or directory) at java. io. File. Input. Stream. open(Native Method) at java. io. File. Input. Stream. <init>(File. Input. Stream. java: 103) at java. io. File. Input. Stream. <init>(File. Input. Stream. java: 66) at java. io. File. Reader. <init>(File. Reader. java: 39) at File. Copy. main(File. Copy. java: 12) 5%

Catching the Exception public class File. Copy { public static void main(String[] args) throws

Catching the Exception public class File. Copy { public static void main(String[] args) throws IOException { Buffered. Reader br = new Buffered. Reader(new Input. Stream. Reader(System. in)); File. Reader r; File. Writer w; System. out. print("Source file name: "); String in. File. Name = br. read. Line(); try { r = new File. Reader(in. File. Name); } catch(File. Not. Found. Exception ex) { System. out. println(ex. get. Message()); System. out. print("Source file name: "); in. File. Name = br. read. Line(); r = new File. Reader(in. File. Name); } } } . . .

Catching the Exception (cont'd) This approach will catch the first instance of a File.

Catching the Exception (cont'd) This approach will catch the first instance of a File. Not. Found. Exception, but only that instance: 5% java File. Copy Source file name: foo (No such file or directory) Source file name: bar Exception in thread "main" java. io. File. Not. Found. Exception: bar (No such file or directory) at java. io. File. Input. Stream. open(Native Method) at java. io. File. Input. Stream. <init>(File. Input. Stream. java: 103) at java. io. File. Input. Stream. <init>(File. Input. Stream. java: 66) at java. io. File. Reader. <init>(File. Reader. java: 39) at File. Copy. main(File. Copy. java: 19) 6% Note that you can use the get. Message() method (inherited by the Exception class) in your handler.

Generating True Looping Behavior public class File. Copy { public static void main(String[] args)

Generating True Looping Behavior public class File. Copy { public static void main(String[] args) throws IOException { Buffered. Reader br = new Buffered. Reader(new Input. Stream. Reader(System. in)); File. Reader r = null; File. Writer w = null; boolean file. Found; do { file. Found = true; System. out. print("Source file name: "); String in. File. Name = br. read. Line(); try { r = new File. Reader(in. File. Name); } catch(File. Not. Found. Exception ex) { file. Found = false; System. out. println(ex. get. Message()); } } while ( !file. Found ); } } . . .

New Output 226% java File. Copy Source file name: foo foo (No such file

New Output 226% java File. Copy Source file name: foo foo (No such file or directory) Source file name: bar bar (No such file or directory) Source file name: X. java Destination file name: Y. java 227%

Another Way public static void main(String[] args) throws IOException { Buffered. Reader br =

Another Way public static void main(String[] args) throws IOException { Buffered. Reader br = new Buffered. Reader(new Input. Stream. Reader(System. in)); File. Reader r = get. File. Reader(br); File. Writer w = get. File. Writer(br); int c; while ((c = r. read()) != -1) w. write(c); w. flush(); }

Generating Looping Behavior Through Recursion private static File. Reader get. File. Reader(Buffered. Reader br)

Generating Looping Behavior Through Recursion private static File. Reader get. File. Reader(Buffered. Reader br) { } System. out. print("Source file name: "); try { String in. File. Name = br. read. Line(); return new File. Reader(in. File. Name); } catch(IOException ex) { System. out. println(ex. get. Message()); return get. File. Reader(br); } Note: No looping code needed. Since the exception is caught, no throws clause is necessary.

Generating Looping Behavior Through Recursion (cont'd) private static File. Writer get. File. Writer(Buffered. Reader

Generating Looping Behavior Through Recursion (cont'd) private static File. Writer get. File. Writer(Buffered. Reader br) { } System. out. print("Destination file name: "); try { String out. File. Name = br. read. Line(); return new File. Writer(out. File. Name); } catch(IOException ex) { System. out. println(ex. get. Message()); return get. File. Writer(br); } Now the only calls in main that can throw an exception are read, write, and flush

A Version of main that Does Not throw public static void main(String[] args) {

A Version of main that Does Not throw public static void main(String[] args) { Buffered. Reader br = new Buffered. Reader(new Input. Stream. Reader(System. in)); File. Reader r = get. File. Reader(br); File. Writer w = get. File. Writer(br); int c; } try { while ((c = r. read()) != -1) w. write(c); w. flush(); } catch(IOException ex) { System. out. println(ex. get. Message()); } Now the program will not crash if/when an I/O error occurs.

Checked vs. Unchecked Exceptions ● ● A program that catches all I/O exceptions may

Checked vs. Unchecked Exceptions ● ● A program that catches all I/O exceptions may still experience a different type of exception (say, a runtime exception) I/O exceptions are ``checked'' by the compiler – ● That is, you are required to either catch them or mention them in a throws clause Unlike I/O exceptions, runtime exceptions are ``unchecked'' – That is, you can choose to ignore them at your peril

Some Checked Exceptions ● ● ● IOException and any of its subclasses Interrupted. Exception

Some Checked Exceptions ● ● ● IOException and any of its subclasses Interrupted. Exception (thrown when a thread is interrupted) Any exception you invent by subclassing Exception

Some Unchecked Exceptions ● Subclasses of Runtime. Exception: – – Arithmetic. Exception Illegal. Argument.

Some Unchecked Exceptions ● Subclasses of Runtime. Exception: – – Arithmetic. Exception Illegal. Argument. Exception Number. Format. Exception Index. Out. Of. Bounds. Exception ● ● Array. Index. Out. Of. Bounds. Exception String. Index. Out. Of. Bounds. Exception – Null. Pointer. Exception – Those that you invent by subclassing Runtime. Exception

Exceptions vs. Errors ● ● Exceptions are processing conditions that a program ought to

Exceptions vs. Errors ● ● Exceptions are processing conditions that a program ought to be able to recover from if it is robust enough Errors are conditions that are ordinarily not recoverable: – Death of a thread – Linking error – Virtual machine error

The Throwable Class ● Exceptions and Errors are both subclasses of the Throwable class:

The Throwable Class ● Exceptions and Errors are both subclasses of the Throwable class: Object Throwable Exception Linkage. Error Thread. Death Virtual. Machine. Error