Handling errors takes care of a major limitation of creating large, robust, maintainable programs.
Let's see how we can handle exceptions in Java.
The ideal time to catch an error is at compile time, before you even try to run the program. However, not all errors can be detected at compile time. Without writing smart code and catching exceptions, your code could turn into an unreadable nightmare.An exceptional condition is a problem that prevents the continuation of the method that you're in.
All you can do is jump out of the current context and relegate that problem to a higher context.
When you throw an exception, several things happen:
Here is how you throw an exception:
| Java Code |
|---|
if(myObject == null)
{
throw new NullPointerException();
}
|
When creating objects in Java, you always create exceptions on the heap using the word new, which allocates storage and calls a constructor. This is how you create an exception.
There are two constructors in all standard exceptions:
Normally, you'll first use the 'new' keyword to create an object that represents the error condition.
You give the resulting reference to 'throw'. The magic of 'throw' keyword is that it "returns" the object from the method, even though that object type isn't normally what the method is designed to return.
When handling exceptions you actually design an alternate return mechanism.
You can also exit from ordinary scopes by throwing an exception. But a value is returned, and the method or scope exits.
If a method throws an exception, it must assume that exception will be caught and dealt with. et's see how we can catch exceptions.
Normally, when an exception is thrown, the method the exception was thrown from will exit in the process of throwing. If you don't want to exit a method everytime an exception is thrown, you can set up a special block within that method to capture the exception. This is called the try block because you try your various method calls there. The try block is a code block, preceded by the keyword try:
|
try { // Code that might generate exceptions } |
| Select all |
When exceptions are thrown they end up in the exception handlers.
There's one exception handler for every exception type you want to catch. Exception handlers immediately follow the try block and are denoted by the keyword catch:
| Java Code |
|---|
try{
// Code that might generate exceptions
}catch(ExceptionType1 ex1) {
// Handle exceptions of ExceptionType1
} catch(ExceptionType2 ex2) {
// Handle exceptions of ExceptionType2
} catch(ExceptionType3 ex3) {
// Handle exceptions of ExceptionType3
}
// etc...
|
| Select all |
When we refer to a catch clause we are talking about an exception handler. The catch clause is like a little method that takes one and only one argument of a particular type. The identifiers (ex1,ex2 ettc..) can be used inside the handler, just like a method argument.
When an exception is hrown, the exception handling mechanism goes hunting for the first handler with an argument that matches the type of the exception.
If you dont cosider catching certain types of exceptions to be necesary, you have the option of creating a handler that catches any type of exception.
You do this by catching the base-class exception type Exception (there are other types of base exceptions, but Exception is the base that's pertinent to virtually all programming activities):
| Java Code |
|---|
catch(Exception e) {
System.err.println("Caught an exception");
}
|
| Select all |
Since the Exception class is the base of all the exception classes that are important to the programmer, you don't get much specific information about the exception, but you can call the methods that come from its base type Throwable:
When an exception is thrown, the exception handling system looks through the nearest handlers in the order they are written.
When it finds a match, the exception is considered handled, and no further searching occurs.
Sometimes you'll want to rethrow the exception that you just caught, particularly when you use Exception to catch any exception. Since you already have the reference to the current exception, you can simply rethrow that reference:
| Java Code |
|---|
catch(Exception e) {
System.err.println("An exception was thrown");
throw e;
}
|
| Select all |
When rethrowing an exception it goes to the exception handlers in the next-higher context. Any further catch clauses for the same try block are still ignored. In addition, everything about the exception object is preserved, so the handler at the higher context that catches the specific exception type can extract all the information from that object.
Often you want to catch one exception and throw another, but still keep the information about the originating exception - Âthis is called exception chaining.
The first example in our tutorial was:
| Java Code |
|---|
if(myObject == null)
{
throw new NullPointerException();
}
|
| Select al |
You don't have to check for null on every reference that is passed into a method.
This is part of the standard run-time checking that Java performs for you, and if any call is made to a null reference, Java will automatically throw a NullPointerException. So the above bit of code is always superfluous.
What happens when you don't catch such exceptions? Since the compiler doesn't enforce exception specifications for these, it's quite plausible that a RuntimeException could percolate all the way out to your main( ) method without being caught.
You can only ignore exceptions of type RuntimeException (and subclasses) in your coding, since all other handling is carefully enforced by the compiler. That is because a RuntimeException represents a programming error.
If a RuntimeException gets all the way out to main( ) without being caught, printStackTrace( ) is called for that exception as the program exits.
There's always a piece of code that you want to execute whether or not an exception is thrown within a try block. For that, you have to use the 'finally' keyword at the end of all the exception handlers.
|
|
| Select all |
Whether or not an exception is thrown, the finally clause is always executed.
'Finally' is necessary when you need to set something other than memory back to its original state.
This is some kind of cleanup like an open file or network connection etc..
The finally statement will also be executed in situations in which break and continue statements are involved.
Nobody posted any comments regarding this story. Be the first!
Discuss