Escolar Documentos
Profissional Documentos
Cultura Documentos
Error detection and handling may be the most important ingredient of any application. Java arms developers with an elegant mechanism for handling errors that produces efficient and organized error-handling code: exception handling.
Handling Exceptions
An exception is an event, which occurs during the execution of a program, that disrupts the normal flow of the program's instructions. When an error occurs within a method, the method creates an object and hands it off to the runtime system.
Handling Exceptions
The object, called an exception object, contains information about the error, including its type and the state of the program when the error occurred. Creating an exception object and handing it to the runtime system is called throwing an exception.
Handling Exceptions
After a method throws an exception, the runtime system attempts to find something to handle it. The set of possible "somethings" to handle the exception is the ordered list of methods that had been called to get to the method where the error occurred. The list of methods is known as the call stack
Exception Hierarchy
Handling Exceptions
The runtime system searches the call stack for a method that contains a block of code that can handle the exception. This block of code is called an exception handler. The search begins with the method in which the error occurred and proceeds through the call stack in the reverse order in which the methods were called.
Handling Exceptions
When an appropriate handler is found, the runtime system passes the exception to the handler. An exception handler is considered appropriate if the type of the exception object thrown matches the type that can be handled by the handler.
Handling Exceptions
The exception handler chosen is said to catch the exception. If the runtime system exhaustively searches all the methods on the call stack without finding an appropriate exception handler, as shown in the next figure, the runtime system (and, consequently, the program) terminates.
Handling Exceptions
The code that might throw certain exceptions must be enclosed by either of the following: 1.) A try statement that catches the exception. The try must provide a handler for the exception, as described in Catching and Handling Exceptions. 2.) A method that specifies that it can throw the exception. The method must provide a throws clause that lists the exception, as described in Specifying the Exceptions Thrown by a Method.
Handling Exceptions
1.) checked exception 2.) error 3.) runtime exception
Checked Exceptions
ClassNotFoundException InterruptedException SQLException IOException FileNotFoundException
Unchecked Exceptions
Unchecked Exceptions are the sub classes of RuntimeException class RuntimeException NullPointerException ArithmeticException ArrayIndexOutOfBoundsException ClassCastException
try{
System.out.println(x/0);
Output :
Caught Finally
} finally { //clean up }
try { // do stuff } // can't have code between try/catch System.out.println("out of try block"); catch(Exception ex) { }
Important Facts
It is illegal to use a try clause without either a catch clause or a finally clause. A try clause by itself will result in a compiler error. Any catch clauses must immediately follow the try block. Any finally clause must immediately follow the last catch clause (or it must immediately follow the try block if there is no catch). It is legal to omit either the catch clause or the finally clause, but not both.
Let's look at the throw statement in context. The following pop method is taken from a class that implements a common stack object. The method removes the top element from the stack and returns the object.
Uncaught Exceptions
class TestEx { public static void main (String [] args) { doStuff(); // calling the method in main (1) } static void doStuff() { doMoreStuff(); // calling another method } static void doMoreStuff() { int x = 5/0; // Can't divide by zero! // ArithmeticException is thrown here } }
Uncaught exceptions
To avoid the above exception we could do 3 things. 1.) static void doMoreStuff() { try{ int x = 5/0; }catch(Exception e ){
System.out.println(Caught);
} }
} }
}
}
Guarded Methods
If we throw a checked exception from a method the compiler will not allow the code to be compiled. Eg : void m (){ throw new IOException(); // This code does not compile }
Guarded Methods
To make the above code compile we have to do any of the following 2 things. 1.) surround the throw statement in a try catch (HANDLING) 2.) add a throws clause to the main method (DECLARING)
Guarded Methods
1.) HANDLING the exception void m (){ try{ throw new IOException(); }catch(Exception e ){ System.out.println(caught) ; }
Guarded Methods
2.) DECLARING the exception void m () throws Exception{ throw new IOException(); }
Overriding Methods
With respect to the method it overrides, the overriding method The overriding method CAN throw any unchecked (runtime) exception, regardless of whether the overridden method declares the exception. The overriding method must NOT throw checked exceptions that are new or broader than those declared by the overridden method.
Overriding Methods
For example, a method that declares a FileNotFoundException cannot be overridden by a method that declares a SQLException, Exception, or any other non-runtime exception unless it's a subclass of FileNotFoundException.
The overriding method can throw narrower or fewer exceptions. Just because an overridden method "takes risks" doesn't mean that the overriding subclass exception takes the same risks.
Overriding Methods
Bottom line: an overriding method doesn't have to declare any exceptions that it will never throw, regardless of what the overridden method declares.
Overriding Methods
If a method is overridden but you use a polymorphic (supertype) reference to refer to the subtype object with the overriding method, the compiler assumes youre calling the supertype version of the method. If the supertype version declares a checked exception, but the overriding subtype method does not, the compiler still thinks you are calling a method that declares an exception (more in Chapter 5). Lets take a look at an example:
class Animal { public void eat() throws Exception { // throws an Exception } } class Dog2 extends Animal { public void eat() { // no Exceptions } public static void main(String [] args) { Animal a = new Dog2(); Dog2 d = new Dog2(); d.eat(); // ok a.eat(); // compiler error // unreported exception } } This code will not compile because of the Exception declared on the Animal eat() method. This happens even though, at runtime, the eat() method used would be the Dog version, which does not declare the exception.
Overloading Methods
Overloaded methods MUST change the argument list. Overloaded methods CAN change the return type. Overloaded methods CAN change the access modifier. Overloaded methods CAN declare new or broader checked exceptions.
Overloading Methods
A method can be overloaded in the same class or in a subclass. In other words, if class A defines a doStuff(int i) method, the subclass B could define a doStuff(String s) method without overriding the superclass version that takes an int. So two methods with the same name but in different classes can still be considered overloaded, if the subclass inherits one version of the method and then declares another overloaded version in its class definition.
Overloading Methods
Be careful to recognize when a method is overloaded rather than overridden. You might see a method that appears to be violating a rule for overriding, but that is actually a legal overload, as follows:
public class Foo { public void doStuff(int y, String s) { } public void moreThings(int x) { } } class Bar extends Foo { public void doStuff(int y, long s) throws IOException { } }
Legal Overloads
Let's look at a method we want to overload: public void changeSize(int size, String name, float pattern) { } The following methods are legal overloads of the changeSize() method: public void changeSize(int size, String name) { } public int changeSize(int size, float pattern) { } public void changeSize(float pattern, String name) throws IOException { }