280 likes | 588 Views
Lecture 3.3. Java Exception Handling. Cheng-Chia Chen. Contents. Traditional approach to program errors/exceptions Java’s exception handling The try statement Exception propagation The catch clause The finally clause. Unexpected conditions which may arise during program execution.
E N D
Lecture 3.3. Java Exception Handling Cheng-Chia Chen
Contents • Traditional approach to program errors/exceptions • Java’s exception handling • The try statement • Exception propagation • The catch clause • The finally clause
Unexpected conditions which may arise during program execution • called exceptions • Examples: • System file or i/o errors, disk full or unavailable, socket connection closed. • Program file or i/o errors, unexpected EOF, file not found. • Programmer errors, array subscript out of bounds, • System errors, unable to load class file, problems with JVM. • Traditional approach to exceptions: • mechanism: return value indicating occurrence of exceptions + special error_code variable storing exact type or details of errors • problems: • 1. Exceptions are not forced to be handled and error checking may be ignored entirely. • 2. difficult to deal with when there are many types of exceptions that need to be handled.
Example 1: // this call may raise exceptions dbh = dbm_open(dbname, 0, GDBM_WRCREAT, … ); // check/handle all possible exceptions raised from previous call. if (dbh == NULL) { // NULL indicates exceptions logTime(); // error code stored in dbm_errno const char *ret = dbm_strerror(dbm_errno); fprintf(stderr, "ERROR Unable to open database: %s.\n", ret); fflush(stderr); return -1; }
Example 2: num = write(fd, buffer, ioSize); if (num == -1) { if (errno == EWOULDBLOCK) { // This condition is unlikely, however, if the internal system buffers // fill it may occur. In this case, do nothing and retry later. logTime(); fprintf(stderr,"WARNING unable to write on fd: %d without blocking.\n", fd); fflush(stderr); return 0; } else { logError("ERROR error writing to fd"); clearErrorFd(fd, fdState); return 0; } }
Problems found from both examples 1. programmer must remember to check for errors each time a statement which can potentially raise a exception is executed. • ex1: if-statement after the first dbm_open() call. • ex2: if-statement after the first write() call. • error handling codes interleaved with normal program statements => reduces the readability and maintainability of the code. 2. different ways of representing error codes / error messages with different global error variables. The programmer must be able to remember all inconsistant error indications of each function. • ex1: null => exception; error code put on dbm_errono • ex2: -1 => exception; error code put on errorno. • same value in errorno and dbm_errono represent different errors.
Java’s Exceptions • An exception is an object that describes an unusual or erroneous situation • Exceptions are thrown by a program, and may be caught and handled by another part of the program • A program can therefore be separated into a normal execution flow and an exception execution flow • An error is also represented as an object in Java, but usually represents a unrecoverable situation and should not be caught
Exception Handling • A program can deal with an exception in one of three ways: • ignore it • handle it where it occurs • handle it an another place in the program • The manner in which an exception is processed is an important design consideration 3
Exception Handling • If an exception is ignored by the program, the program will terminate and produce an appropriate message • The message includes a call stack trace that indicates on which line the exception occurred • The call stack trace also shows the method call trail that lead to the execution of the offending line • See Zero.java 4
public class Zero { static int divide(int x,int y) { return x/y; // exception occurs here } public static void main(String[] args) { int x = 10; int y = 0; System.out.println ( divide(x,y)); // and here } // method main } // class Zero java Zero java.lang.ArithmeticException: / by zero at Zero.divide(Zero.java:3) at Zero.main(Zero.java:8) Java’s call stack on executing Zero
The try Statement • To process an exception when it occurs, the line that throws the exception is executed within a try block • A try block is followed by one or more catch clauses, which contain code to process an exception • Each catch clause has an associated exception type • When an exception occurs, processing continues at the first catch clause that matches the exception type • See Product.java 5
import java.io.*; public class Product { public static void main (String[] args) { int x = UserReader.readInt(“Enter a number: "); int y = UserReader.readInt("Enter another number: "); System.out.println ("The product is: " + x*y ); } // method main } // class Adding class UserReader { public static int readInt (String prompt) { BufferedReader stdin = new BufferedReader (new InputStreamReader(System.in)); int number = 0; boolean valid = false;
while (! valid) { System.out.print (prompt); System.out.flush (); try { // statements possibly throwing exceptions put here!! number = Integer.parseInt (stdin.readLine()); valid = true; } catch (NumberFormatException exception) { System.out.println ("Invalid input. Try again."); } catch (IOException exception) { System.out.println ("Input problem. Terminating."); System.exit(0); } } return number; }// method readInt } // class UserReader
Exception Propagation • If it is not appropriate to handle the exception where it occurs, it can be handled at a higher level • Exceptions propagate up through the method calling hierarchy until they are caught and handled or until they reach the outermost level • A try block that contains a call to a method in which an exception is thrown can be used to catch that exception • See PropagationDemo.java 6
public class Propagation { static public void main (String[] args) { ExceptionScope demo = new ExceptionScope(); System.out.println("program beginning"); demo.level1(); System.out.println("program ending"); } // method main } // class Propagation class ExceptionScope { public void level3 (int a) { int c = 1; System.out.println("level3 beginning"); current = c / a; // divided by zero System.out.println("level3 ending"); } // method level3
public void level2() { System.out.println("level2 beginning"); level3 (0); System.out.println("level2 ending"); } // method level2 public void level1() { System.out.println("level1 beginning"); try { level2(); } catch (ArithmeticException p) { System.out.println (p.getMessage()); p.printStackTrace(); } System.out.println("level1 ending"); } // method level1 } // class ExceptionScope
Exception propagation level1() : … try{ … level2() …} catch(ArithmeticException p) {…} …. main() : … demo.level1() … level2() : … level3() … level3() : … c = c / 0; // divided by zero … normal flow exception flow
Types of Exceptions • An exception is either checked or unchecked • A checked exception can only be thrown within a try block or within a method that is declared (at the throws-clause of the method header) to throw that exception • The compiler will complain if a checked exception is not handled appropriately • An unchecked exception does not require explicit handling, though it could be processed that way • In previous example, ArithmeticException is an unchecked exception, hence it need not be declared even it is not catched at method level3() and level2(). 7
The throw Statement • A programmer can define an exception by extending the appropriate class • Exceptions are thrown using the throw statement: throw exception-object; • See ThrowDemo.java • Usually a throw statement is nested inside an if statement that evaluates the condition to see if the exception should be thrown 8
import java.io.IOException; public class ThrowDemo { public static void main (String[] args) throws MyExp { MyExp p = new MyExp ("Alert!"); throw p; // execution never gets to this point } // method main } // class ThrowDemo class MyExp extends IOException { MyExp (String message) { super (message); } // constructor Ooops } // class Ooops
The finally Clause • A try statement can have an optional clause designated by the reserved word finally • If no exception is generated, the statements in the finally clause are executed after the statements in the try block complete • Also, if an exception is generated, the statements in the finally clause are executed after the statements in the appropriate catch clause complete 9
The finally Clause • Exception Handling: try { code that may generate exception; } catch (Exception1 e1) { code to handle exception of type Exception1; } catch( …. } catch (ExceptionN eN) { code to handle exception of type ExceptionN; } finally { code that are guaranteed to be executed before (normally or abnormally) leaving this try-catch statement; } 9
(Part of) the Exception Hierarchy Object Throwable • Eorror : • LinkageError, ThreadDeath, VirtualMachineError, AWTError • Exception: • RunTimeError • ArithmeticException • IndexOutOfBoundException • NullPointerException • … • IllegalAccessException • NoSuchMethodException • ClassNotFoundException • IOException • … • Note: Checked exception must be either catched or declared at the throws-clause of the method header. • All Throwable but Error and RuntimeException are checked Exceptions.
What can we get from an Exception java.lang.Throwable: • Constructor Summary • Throwable() : Constructs a new Throwable with null as its error message string. • Throwable([ [String msg] [, Throwable cause ]]) : Constructs a new Throwable with the specified error message and/or cause. • Method Summary • Throwable fillInStackTrace() : Fills in the execution stack trace. • String getLocalizedMessage() : Creates a localized description of this Throwable. • String getMessage() : Returns the error message string of this throwable object. • Throwable getCause(); • void printStackTrace(), printStackTrace(PrintStream s), printStackTrace(PrinterWriter s) : Prints this Throwable and its backtrace to the standard error stream or s. • StackTraceElement[] getStackTrace() void setStackTraceElement(StackTrace[]) • String toString() : Returns a short description of this throwable object. java.lang.Exception: • Constructors: Exception(), Exception(String). • All methods are inherited from Throwable.
StackTraceElement • An element in a stack trace, as returned by Throwable.getStackTrace(). • Each element represents a single stack frame. • All stack frames except for the one at the top of the stack represent a method invocation. • The frame at the top of the stack represents the the execution point at which the stack trace was generated. • Typically, this is the point at which the throwable corresponding to the stack trace was created. • Methods • boolean equals(Objectobj) • String getClassName() • StringgetFileName() • int getLineNumber() • String getMethodName() • int hashCode() • boolean isNativeMethod()