280 likes | 412 Views
Exceptions. In this lecture: What are exceptional situations in a program How does one deal with them The Java exception mechanism. What is an Exception?. An exception is an event that occurs during the execution of a program that disrupts the normal flow of instructions. Examples:
E N D
Exceptions • In this lecture: • What are exceptional situations in a program • How does one deal with them • The Java exception mechanism
What is an Exception? • An exception is an event that occurs during the execution of a program that disrupts the normal flow of instructions. • Examples: • hard disk problem • accessing an out-of-bounds array element • passing an illegal argument to a method (clock example) • trying to invoke a method on a null pointer • division by zero • In all these cases we say that the program encountered a runtime error • The Java exception mechanism is designed to handle such situations
Example: The Clock Class Revisited • Consider the following code: Clock israelTime = new Clock(9,0,0); Clock losAngelesTime = new Clock(); losAngelesTime.setTime(israelTime.getHours() - 10,0,0); // oops… wrong value • We handled the situation by saying “if the clock programmer invokes the method with an illegal argument, then we ignore the call and the clock doesn’t change its value” • This prevents the clock from representing an illegal time value • BUT: this approach is an ideal source of bugs, since the programmer has no indication that an exception occurred!
Exception Handling Approaches • Bad approaches: • Display a message to the user • Don’t even attempt to detect an exception • Better approaches: • Return a value indicating an error occurred • Detect an exception, prevent it from being harmful • Even better approach: • When the programmer chooses not to deal with an exception, program execution ceases • The programmer always has the option of dealing with an exception
The Java Exception Mechanism • An exception object is created by the method in which the exception occurred, encapsulating information about the exception and state of program when it happened • This exception is handed (thrown) to the runtime system - Java interpreter - which attempts to find “someone” (a piece of code) to handle the exception (we will see how shortly) • If the appropriate “someone” to handle the exception is not found - the program terminates operation (“crashes”) with an appropriate message
Example 1 class ExceptionTest { public static void main(String[] args) { int[] ai = new int[4]; a[4] = 0; } } Output of program: java.lang.ArrayIndexOutOfBoundsException: 4 at ExceptionTest.main(ExceptionTest.java:3)
Example 2 class NullPointerTest { public static void main(String[] args) { String str = null; Sting str1 = str.toLowerCase(); } } Output of program: java.lang.NullPointerException: 4 at NullPointerTest.main(NullPointerTest.java:3)
Catching an Exception • A programmer may decide to deal with the situation by catching the exception, if it occurs • This is done using a “try…catch” clause: try { do dangerous operations which might throw exceptions } catch an exception { do whatever it takes to handle the exception } Exception Handler
Catching an Exception class ExceptionTest { public static void main(String[] args) { int[] ai = new int[4]; try { a[4] = 0; } catch (ArrayIndexOutOfBoundsException e) { System.out.println(“Array index problem:”); System.out.println(e); } } }
Types of Exceptions • Java defines many types of exceptions which might occur during program flow. Some of them are: • IllegalArgumentException - Passing an illegal argument to a method. Example: Math.pow(0,0) • NullPointerException • ArrayIndexOutOfBoundsException • ArithmeticException - Division by zero • StringIndexOutOfBoundsException • Of course, requiring the programmer to catch every out-of-bound array reference is horrifying and absurd, but: • there are other types of exceptions which must be dealt with • the programmer must have the ability to catch any exception it wishes (e.g, for debugging purposes)
Throwing Your Own Exception /** * Sets the time read by the clock. * @param hours The hours to be set (0-23) * @param minutes The minutes to be set (0-59) * @param seconds The seconds to be set (0-59) * @exception IllegalArgumentException if one of the * parameters is not in the * allowed range. */ public void setTime(int hours, int minutes, int seconds) { if ((seconds >= 0) && … && (hours < 24)) { this.hours = hours; this.minutes = minutes; this.seconds = seconds; } else throw new IllegalArgumentException("Clock arguments invalid"); }
Clock arguments must be correct! Clock: The Right Way public class ClockTest { public static void main(String[] args) { Clock c = new Clock(); try { c.setTime(50,50,50); } catch(IllegalArgumentException e) { System.out.println(e); e.printStackTrace(); } } } Output: java.lang.IllegalArgumentException: Clock arguments invalid at Clock.setTime(Clock.java:61) at ClockTest.main(ClockTest.java:5)
“Traditional” Error Handling • In traditional programming, error detection, reporting, and handling often lead to confusing spaghetti code. • Example: readFile { open the file; determine its size; allocate that much memory; read the file into memory; close the file; }
What is the Problem? • At first glance this function seems simple enough, but it ignores all of these potential errors: • 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 - The Old Way errorCodeType readFile { initialize errorCode = 0; open the file; if (theFileIsOpen) { determine the length of the file; if (gotTheFileLength) { allocate that much memory; if (gotEnoughMemory) { read the file into memory; if (readFailed) { errorCode = -1; } } else { errorCode = -2; } else { errorCode = -3; // etc. etc ...
Error Handling Using Exceptions readFile { try { open the file; determine its size; allocate that much memory; read the file into memory; close the file; } catch (fileOpenFailed) { doSomething; } catch (sizeDeterminationFailed) { doSomething; } catch (memoryAllocationFailed) { doSomething; } catch (readFailed) { doSomething; } catch (fileCloseFailed) { doSomething; } } main program flow exceptional situations
Propagating Errors Through Method Calls - The Old Way method1 { call method2; } method2 { call method3; } method3 { call readFile; }
Propagating Errors Through Method Calls - The Old Way method1 { errorCodeType error; error = call method2; if (error) doErrorProcessing; else proceed; } errorCodeType method2 { errorCodeType error; error = call method3; if (error) return error; else proceed; } errorCodeType method3 { errorCodeType error; error = call readFile; if (error) return error; else proceed; }
Exceptions: Propagation Up the Call Stack method1 { try { call method2; } catch (exception) { doErrorProcessing; } } method2 { call method3; } method3 { call readFile; }
method1 { try { call method2; } catch (exception) { doErrorProcessing; } } method2 { call method3; } method3 { call readFile; }
method1 { try { call method2; } catch (exception) { doErrorProcessing; } } method2 { call method3; } method3 { call readFile; }
method1 { try { call method2; } catch (exception) { doErrorProcessing; } } method2 { call method3; } method3 { call readFile; }
method1 { try { call method2; } catch (exception) { doErrorProcessing; } } method2 { call method3; } method3 { call readFile; }
method1 { try { call method2; } catch (exception) { doErrorProcessing; } } method2 { call method3; } method3 { call readFile; }
method1 { try { call method2; } catch (exception) { doErrorProcessing; } } method2 { call method3; } method3 { call readFile; }
Runtime vs. Other Exceptions • By now, we’ve seen a special class of exceptions which is called Runtime Exceptions. • Some exceptions in Java must be caught explicitly, or else, the method in question must declare it is throwing an exception: public politicallyCorrectMethod { try { do something which may throw MustBeCaughtException; } catch (MustBeCaughtException e) { clear up the mess; } }
Runtime vs. Other Exceptions public ignorantMethod throws MustBeCaughtException{ do something which may throw MustBeCaughtException; // if it fails, the method who called // me (or the method who called it, etc.) // will clear up the mess... } • We will learn more about such exceptions in the future