* Your assessment is very important for improving the workof artificial intelligence, which forms the content of this project
Download Chapter 14
Survey
Document related concepts
Scala (programming language) wikipedia , lookup
Java (programming language) wikipedia , lookup
Java performance wikipedia , lookup
Covariance and contravariance (computer science) wikipedia , lookup
Java ConcurrentMap wikipedia , lookup
Falcon (programming language) wikipedia , lookup
Class (computer programming) wikipedia , lookup
Go (programming language) wikipedia , lookup
Object-oriented programming wikipedia , lookup
Java syntax wikipedia , lookup
Name mangling wikipedia , lookup
Control flow wikipedia , lookup
Standard ML wikipedia , lookup
C Sharp (programming language) wikipedia , lookup
Transcript
COMP 356 Programming Language Structures Notes for Chapter 14 of Concepts of Programming Languages Exception Handling Exceptions: • allow program units to signal error or other “exceptional” conditions • allow error handling code to be separate from other code • provide flexibility in where errors are handled This is especially important for “library” units that may be reused in many programs, because different client code will usually require errors to be handled in different ways. Languages with exception handling typically include: • a mechanism for signaling an exceptional condition (called raising or throwing an exception) • a mechanism for detecting when an exception has been raised and taking some action in response (called handling or catching an exception) 1 Exceptions in Java Java has 2 kinds of exceptions: • checked exceptions – typically defined by the programmer – methods must declare any checked exceptions that they could throw • unchecked exceptions – typically built-in, such as exceptions to indicate division by 0 or dereferencing of a null reference – methods need not declare that they could throw unchecked exceptions (since almost all methods could throw them) 1.1 Mechanics • errors are signaled by throwing an exception (using keyword throw) • any method whose body could throw a checked exception (that isn’t handled in the method itself) must be declared with a throws clause containing a comma separated list of all exceptions that could be thrown • exceptions are handled using keywords try and catch surrounding a block that could throw an exception Example (from class IntQueue): public int dequeue() throws EmptyQueueException { // return next queue element, or throw exception if queue is empty int res = 0; if (tail == null) throw new EmptyQueueException("can’t dequeue empty queue"); else { ... 1 } } ... // code that calls dequeue try { System.out.println(iq.dequeue()); System.out.println(iq.isEmpty()); System.out.println(iq.dequeue()); } catch (EmptyQueueException e) { System.out.println(e); // prints the string passed to the constructor } 1.2 Defining Exceptions In Java, exceptions are objects defined by exception classes: • all exception classes must extend the system class Throwable (directly or indirectly) • three system subclasses of Throwable that can be extended: – Exception – RuntimeException – Error • any exception class that extends Exception defines a checked exception • other exception classes define unchecked exceptions • system (built-in) exceptions extend RuntimeException or Error, and so are unchecked • programmer-defined exceptions should almost always be checked exceptions (extend Exception): – forces documentation that the exception could be thrown (in the throws clause of the method declaration – forces client code to explicitly deal with error conditions Example - class EmptyQueueException: public class EmptyQueueException extends Exception { public EmptyQueueException(String mes) { // invoke superclass constructor to set message for this instance super(mes); } } An exception is thrown by constructing an object of the appropriate exception class and using it with keyword throw. 1.3 Handling Exceptions A catch clause will handle objects of all subclasses of the class specified as its parameter. For example: 2 try { .. } catch (Exception e) { .. } will catch all checked exceptions (which likely includes all programmer-defined exceptions), and so does not differentiate exceptional conditions. Better approach: • declare an exception class for each kind of error • handle exceptions using specific exception class parameters in the catch clauses. General form: try { ... } catch (ExceptionSub1 e1) { ... } catch (ExceptionSub2 e2) { ... } catch (ExceptionSubn en) { ... } finally { ... } where each ExceptionSubi is a different subclass of Exception. When an exception is thrown in the try construct, the catch clauses are tried in order, and the first that matches the exception is used. Hence, the following is bad and is rejected by the compiler: class SuperException extends Exception { ... } class SubException extends SuperException { ... } ... try { ... } catch (SuperException e1) { ... } catch (SubException e2) { ... } because the second catch clause can never be used. The code contained in the (optional) finally clause is executed whether an exception is thrown in the try construct or not. This is useful for “cleanup” code (closing files, other freeing of resources, ...) that must always be executed. Binding of exceptions to handlers is both static and dynamic: • static: if try constructs are nested, then the nearest enclosing catch clause (from the point where the exception is thrown) that matches is used. • dynamic: if the method that throws the exception does not have a handler for it, then the exception travels up the method call chain (runtime stack) until the exception is caught or the chain is exhausted (no more method invocations are active). Hence, any method calling another method that throws a checked exception E must either catch E or throw E itself. 3 When an exception is caught, the code in the catch clause is executed, and then execution resumes immediately after the last catch clause (or the finally clause if present) of the try construct. If an exception is thrown but never caught, then the program terminates. A catch clause can rethrow the exception that it caught (using keyword throw with no operand) or create and throw a new exception. Such an exception will not be caught in the current try construct, so there is no danger of creating a “loop”. This approach is useful when some local error handling is useful, but more needs to be done at some other point in the program. 2 Exceptions in C++ Exceptions in C++ are very similar to those in Java, but there are some important differences. Similarities: • try constructs with catch clauses are used to handle exceptions • the keyword throw is used to throw exceptions • a catch clause can rethrow an exception (using throw with no operand) or throw a new exception • binding of exceptions to handlers is identical to the Java case Differences: • values of any type (not just instances of exception classes) can be used as exceptions • all exceptions are programmer-defined • there is no distinction between checked and unchecked exceptions • in Java, a method that overrides a superclass method can only throw exceptions that the overriden method could throw. In C++, a member function overriding a superclass function can throw any exception, regardless of those thrown by the overriden function. Example: int fun() { ... if (error1()) throw 2; ... if (error1()) throw 2.0; ... } ... try { int i = fun(); } catch (int) { // catches first exception, doesn’t observe value thrown ... } catch (double d) { // catches second exception, observes value thrown ... } catch (...) { // catches any exception not caught earlier ... } 4 A catch clause that catches exceptions of type T will also catch exceptions of type const T, T& and const T&. If T is a class type, then the catch clause will also catch exceptions of any subclass type. A function can list the exception types that it throws using the keyword throw in the header. For example: int fun() throw (int, double) { ... } This is similar to the use of throws in Java – if the header contains throw, then the function can only throw the listed exceptions. However: • in Java, a method with no throws clause in its header can not throw any checked exceptions • in C++, a function with no throw clause in its header can throw any exception. A throw clause with an empty list of exception types, i.e.: int fun() throw () { ... } indicates that the function can not throw any exceptions. Final notes: • many programmers prefer Java-style exception handling because it is: – simpler – more object-oriented – easier to associate meaningful names with exception classes than with arbitrary types • exceptions should only be used for conditions that are exceptional or unusual. Using them for expected conditions such as end-of-file is inefficient and makes code difficult to read. 5