meeting -*- outline -*- * Exception Handling Goal is to explain this new (to most students) feature of Java. refs: Arnold, Gosling, Holmes, The Java Programming Language 3rd ed., Addison Wesley, 2000, chapter 8 Q: Have you used exceptions in C++? ** motivation This is perhaps too brief to be convincing, but this isn't a PL design class and we have other things to do... ------------------------------------------ MOTIVATION FOR EXCEPTION HANDLING How to make a "bullet-proof" abstraction? Returning a status code: - inefficient in the normal case - users who forget aren't warned ==> insecure - checking status gets in the way ==> hard to read programs Exit the program if problems found: - inflexible ==> poor reuse Require callers to check preconditions: - doesn't work for untrusted clients ==> insecure - hard for clients to check sometimes ==> inefficient, hard to read Better: exceptions, try/catch statements ------------------------------------------ Q: So when should you use exceptions in a design? when you want to return a "abnormal" status indication, when you can't trust the caller to check perconditions ** exception mechanism Overall this is like a game of catch, one piece of code gets ready to catch an exception, another piece of code "throws" an exception object it creates, and it's caught by the piece of code that was prepared to catch it. *** terms ------------------------------------------ EXCEPTION HANDLING MECHANISMS A convenient form of passing blocks Terms: An exception is an object that may be The code that is executed in response ------------------------------------------ ... *thrown* (or *signalled*) by piece of code ... *catches* the exception and is called a *handler* (or catchblock in Java) ** in Java *** exception hierarchy ------------------------------------------ EXCEPTION TYPES IN JAVA All exceptions are subclasses of Throwable Unchecked exceptions are subclasses of either Error or RuntimeException Throwable Error AWTError LinkageError ThreadDepthError VirtualMachineError OutOfMemoryError ... Exception AWT Exception ClassNotFoundException CloneNotSupportedException IOException EOFException FileNotFoundException ... RuntimeException ArithmeticException ArrayStoreException ClassCastException SecurityException IndexOutOfBoundsException NullPointerException IllegalArgumentException ... ------------------------------------------ In Java, the RunTimeException and Error subclasses are unchecked (the compiler doesn't see if they are handled statically) Q: Advantages of a hierarchy? can test for one element in the hierarchy, covers everything underneath it. Leads to compression of code for handlers. *** declarations in Java of what exceptions a method can throw ------------------------------------------ DECLARING EXCEPTIONS THROWN BY METHODS IN JAVA Syntax for declaring exceptions that may be thrown by a method: throws [, ] ... Example: char readChar() throws IOException { ...readByte() ... } byte readByte() throws IOException { ... } ------------------------------------------ In Java, all *checked* exceptions that can either be thrown explicitly or can propogate out of a method must be declared Classic example of checked exception is IOException Q: Why? so the compiler, and clients, can check that all exceptions are either handle or propogated (safety) *** throwing exceptions ------------------------------------------ THROWING AN EXCEPTION To throw an exception you have to - create an exception object, - use "throw" to throw it. Syntax: throw ; Example: throw new IOException("bad file"); ------------------------------------------ semantics of throw: - unwind all blocks (get rid of their storage, run any finalizers) between the throw and the nearest, dynamically enclosing catchblock whose type is a supertype of the thrown exception. - start execution in that block *** catching exceptions ------------------------------------------ CATCHING AN EXCEPTION Syntax: try [catch ( ) ] ... [finally ] Example: try { } catch (IOException ioe) { System.err.println(e.getMessage()); } catch (NullPointerException npe) { System.err.println(npe); throw npe; } finally { myFile.close(); } ------------------------------------------ semantics of try: run the block, if an exception is raised, if the thrown object inherits from the type on a catch (look from the beginning), then bind the identifier to that object, and run the code of the corresponding block if there is a finally block, do that afterwards, in every case. if an exception was raised, but not caught, then the same exception is raised by the current method. Q: What else needs to be said? what happens if an exception is raised in the finally block and there's a pending exception being thrown? the one in the finally block wins, and the other throw is forgotten