Java exception mechanism • when an error or exceptional condition occurs, you throw an exception which is caught by an exception handler try { // statements that may throw an exception.. if (someCondition) Exceptions and error handling throw new ExceptionName (); } catch (ExceptionName e) { // executed for ExceptionName } finally { // executed whether exception or not } 1 2 On exception handling Java exception mech. (cont.) • a library shouldn't produce diagnostic output at an • when searching for a catch block to handle an end user, or independently terminate a program exception thrown, Java goes upward through the • instead, throw an exception and let a caller decide dynamic activation stack of method calls until it finds a matching catch block • not every program needs to handle exceptions • should use exceptions only for "exceptional" safely: conditions, not for ordinary control flow – a simple application may produce a suitable • may enable recovery from a failure diagnostic, let the system release all acquired • can ensure release of critical resources resources, and let the user re-run the program with a more suitable input • at least, enables graceful shutdown 3 4 1
Benefits of exception handling Handling exceptions Generally, there are many ways to handle an exception: 1. let Java handle it (but don't supress it) • separates of error handling from normal processing 2. fix the problem that let to the exception and resume • provides a systematic way to report and handle the program; but often, erroneous conditions are exceptional situations (failures or errors) difficult or impossible to fix • exceptions are necessary for making reusable 3. log the problem and resume the program libraries and components work: 4. log the problem and rethrow the exception – the library component may detect an error, e.g., 5. chain a low-level exception within a new higher-level violation of a precondition, but cannot know how exception (wrap inside as a parameter) and throw to handle it that 6. print/display/log out an error message and let the program terminate 5 6 Handling exceptions (cont.) Java exception class hierarchy • no one-for-all solution, depends strongly on the specific requirements of the application • it may well be OK to simply let the program terminate itself, and let the user try with better input 7 8 2
Checked vs. unchecked exceptions Guidelines • checked exceptions are either caught by the method • avoid unnecessary us e of exceptions in which they occur, or you must declare that the • exception handling is not meant to replace a simple method throws the exception test; for example: • checked exceptions force the programmer to deal – reaching the end of a list should not throw a with exceptional conditions; error situations become exception explicit and in principle the program becomes more reliable – the API offers a query method ( hasNext ) for that • unchecked exceptions extend RuntimeException – but then going past the end should throw and, if uncaught, are handled by Java • NoSuchElementException is a run-time • use checked exceptions for recoverable conditions exception that indicates a programming error and RuntimeExceptions for programming errors • don't wrap every statement in a separate try block • other object-oriented languages (C++, C#) don't have – "throw early, catch late" at a higher-level system checked exceptions (but Clu did) 9 10 Guidelines (cont.) Guidelines (cont.) • don't suppress or ignore exceptions try { • in some situations, the programmer may "know" . . . some code that throws SomeException that the code cannot throw any exceptions } catch (SomeException ex) { whatsoever // OK: don't care • of course, then it should be well documented and } checked: • if a checked exception does not make sense to you, try { don't hesitate to convert it into an unchecked . . . // actually cannot throw exceptions exception and throw it again } catch (SomeException e) { } catch (SomeException ex) { assert false; // so shouldn't get here throw new RuntimeException (ex) } chaining constructors available since version 1.4 • 11 12 3
Guidelines (cont.) Guidelines (cont.) Favor the use of standard exceptions, for example: • but don't catch unnecessarily high-level exceptions • IllegalArgumentException : parameter value is try { inappropriate . . . some code that throws exceptions • IllegalStateException : state is inappropriate for method call (before remove must call next ) } catch (Exception ex) { • NullPointerException : null value where prohited } • IndexOutOfBoundsException : invalid index • unchecked exceptions inherit RuntimeException • ConcurrentModificationException : modification of class which inherits Exception object has been detected where prohibited • the code above ignores all unchecked exceptions, • UnsupportedOperationException : object does not as well support method 13 14 Exception translation Guidelines (cont.) • for example, a get () method may call more primitive • document all exceptions thrown by each method operations with their own exceptions; the method using the Javadoc @throws tag can perform exception translation : public E get (int index) { • for debugging, the string represention of an exception should contain the values of all objects ListIterator it = listIterator (index); that "contributed" to the exception try { return it.next (); • higher layers can catch lower-level exceptions, and in their place, throw exceptions that are explainable in } catch (NoSuchElementException e) { terms of the higher-level abstraction throw new IndexOutOfBoundsException ("Index: " + index); } } 15 16 4
Exception chaining Failure atomicity • in exception chaining a lower-level exception is stored by the higher-level exception for debugging purposes: • ideally, attempt to achieve failure atomicity : try { – a failed method should leave the system in the lowLevelOperation (); state it was in prior to the call } catch (LowLevelException e) { • in principal, recovery is not possible if the system is throw new HighLevelException (e); left in an undetermined, possibly faulty state // has chaining constructor • failure atomicity is expecially important for checked } exceptions, from which the caller is expected to • additionally, the class Throwable provides methods recover getCause () and initCause ( Throwable cause ) to get and set the original cause of the error situation 17 18 Failure atomicity (cont.) Using finally blocks • finally clauses release resources no matter what public E pop () { // a bit trivial but illustrative • a finally clause can be be used without a catch if (size () == 0) clause: throw new NoSuchElementException (); Graphics g = image.getGraphics (); // now can safely modify the contents: try { E result = elements [--size]; code that might throw exceptions } finally { elements [size] = null; // eliminate old reference g.dispose (); return result; } } 19 20 5
Using finally blocks (cont.) Problems with finally blocks • you can decouple try/catch and try/finally to make your code more readable: InputStream in = . . .; • if a finally block itself throws an exception, the try { original exception becomes permanently lost try { // ensure that stream is closed code that might throw exceptions • as a rule, all clean-up code such as finally should be programmed not to throw any exceptions } finally { in.close (); – very hard to enforce in practice, and } – unfortunately, not all library methods necessarily } catch (IOException e) { // reports errors respect the right spirit of exception handling show error dialog } • this resembles the use C++ destructors 21 22 Problems finally blocks (cont.) • if a try block or a catch clause contains a return statement, the finally block is (as always) executed before the return • however, if the finally block itself contains a return, it then masks off the original return public static f (int n) { try { ... return n * n; } ... } finally { if (n == 2) return 0; // strange and unexpected } } 23 6
Recommend
More recommend