Exceptions: Don't
get thrown for a loss
Tutorial Details:
Exceptions: Don't get thrown for a loss
Exceptions: Don't get thrown for a loss
By: By Tony Sintes
Catch the differences between checked and runtime exceptions
February 8, 2002
Please explain the difference between checked exceptions and runtime exceptions? When would I throw them, and when would I catch them?
Java provides two main exception types: runtime exceptions and checked exceptions. All checked exceptions extend from java.lang.Exception , while runtime exceptions extend from either java.lang.RuntimeException or java.lang.Error .
Two aspects differentiate checked exceptions from runtime exceptions: mechanical and logical.
The mechanics
From a mechanical viewpoint, runtime exceptions and checked exceptions differ in how you declare the method that throws the exception, and how you handle the exception when it's thrown. Consider the following checked exception definition:
public class CheckedException extends Exception {
public CheckedException() {}
public CheckedException( String message ) { super( message ); }
}
The following class has a number of methods that throw exceptions:
public class ExceptionalClass {
public void method1() throws CheckedException {
// ... some code
throw new CheckedException( "something bad happened" );
}
public void method2( String arg ) {
if( arg == null ) {
throw new NullPointerException( "arg passed to method2 is null" );
}
}
public void method3() throws CheckedException {
method1();
}
}
Right away you'll notice that both method1() and method2() throw exceptions, but only method1() has an exception declaration. You'll also notice that method3() doesn't throw an exception itself, but its signature indicates that it may throw a CheckedException . Before I tell you why, consider the following main method:
public static void main( String [] args ) {
ExceptionalClass example = new ExceptionalClass();
try
{
example.method1();
example.method3();
}
catch( CheckedException ex ) {
}
example.method2( null );
}
When a call is made to method1() , you must make the call from within a try/catch block. In this case, it's a checked exception because you must catch it. Checked exceptions are always declared as thrown in the method signature. The signature lets the method's caller know that an exception may occur as a consequence of the call. If the exception does get thrown, the caller must be prepared to do something about it.
Contrast method1() with method2() . When you make a call to method2() , you don't have to do so within a try/catch block. Since you do not have to catch the exception, the exception is said to be unchecked; it is a runtime exception. A method that throws a runtime exception need not declare the exception in its signature.
Now, look back at method3() . It makes a call to method1() without making the call in a try/catch block. method3() avoids not catching the exception by declaring that it may also throw the exception thrown by method1() . Instead of catching the exception, method3() simply passes the exception along. Analogously, you could have dispensed with the try/catch block in the main method by declaring that it throws CheckedException . (I only mention this to give you a second reference point; you should never declare a main as throwing an exception.)
Here's a summary of the mechanical aspects of exceptions:
Runtime exceptions:
A method signature does not need to declare runtime exceptions
A caller to a method that throws a runtime exception is not forced to catch the runtime exception
Runtime exceptions extend from RuntimeException or Error
Checked exceptions:
A method must declare each checked exception it throws
A caller to a method that throws a checked exception must either catch the exception or throw the exception itself
Checked exceptions extend from Exception
The logic
From a logical viewpoint, checked exceptions and runtime exceptions serve two separate purposes. Checked exceptions indicate an exceptional condition from which a caller can conceivably recover. Conversely, runtime exceptions indicate a programmatic error from which a caller cannot normally recover.
Checked exceptions force you to catch the exception and to do something about it. Take a look at the constructors for java.net.URL . Each constructor may throw a MalformedURLException , an example of a checked exception.
Imagine that you've written a simple program that prompts the user for a URL. Using that URL, the program retrieves a page. If something is wrong with the URL the user enters, the constructor will throw an exception. Since the URL constructor throws a checked exception, the program must catch the exception and try to recover. In the case of the bad URL, the program could ask the user to retype it.
Now, consider the following method:
public void method() {
int [] numbers = { 1, 2, 3 };
int sum = numbers[0] + numbers[3];
}
Executing method() will always yield an ArrayIndexOutOfBoundsException since we are trying to read past the end of the array. Remember, an array index i must be:
0 <= i <= (array.length - 1)
The method caller has no recourse because the caller cannot do anything meaningful in response to the error. This method, as well as method2() , represents a runtime exception example. As I mentioned above, runtime exceptions indicate programmatic errors. Programmatic errors are normally unrecoverable bugs, so the proper recovery is to fix the error in the code.
As a rule of thumb, you should always catch a checked exception once you reach a point where your code can make a meaningful attempt at recovery. However, it is best not to catch runtime exceptions. Instead, you should allow runtime exceptions to bubble up to where you can see them.
If you do catch runtime exceptions, you risk inadvertently hiding an exception you would have otherwise detected and fixed. As a result, catching runtime exceptions complicates unit and regression testing. While testing, seeing a stack trace or allowing the test to catch and report runtime exceptions lets you quickly identify problems. Some programmers advocate catching and logging runtime exceptions, but I disagree because that makes you read through logs while you unit test your code. A unit test should indicate whether the test passed or failed without manual verification from a log. Let the unit test catch the exception, not the code being tested.
Catching runtime exceptions also leads to a worse problem: what exceptions do you catch, and when do you catch them? Runtime exceptions are undeclared, so how do you know what you should catch? How do you know there's an exception to catch? Certainly you wouldn't place try/catch blocks around every method call and array access you perform?
This page formated for crawlers and browsers that don't support scripts and tables.
Home
EZone
Read
Tutorial at: Click here to view the tutorial
Rate Tutorial: Exceptions: Don't
get thrown for a loss
View Tutorial: Exceptions: Don't
get thrown for a loss
Related
Tutorials:
Designing with
exceptions - JavaWorld - July 1998
Designing with
exceptions - JavaWorld - July 1998 |
Improve the
robustness and performance of your ObjectPool - JavaWorld - August 1998
Improve the
robustness and performance of your ObjectPool - JavaWorld - August 1998 |
Multicast the chatwaves - JavaWorld October 1999
Multicast the chatwaves - JavaWorld October 1999 |
How to avoid traps and correctly override methods from java.lang.Object - JavaWorld January 1999
How to avoid traps and correctly override methods from java.lang.Object - JavaWorld January 1999 |
Java performance programming,
Part 2: The cost of casting - JavaWorld December 1999
Java performance programming,
Part 2: The cost of casting - JavaWorld December 1999 |
Use HTTPS in your
Java client code
- JavaWorld
Use HTTPS in your
Java client code
- JavaWorld |
Add MP3 capabilities to Java Sound with SPI - JavaWorld November
2000
Add MP3 capabilities to Java Sound with SPI - JavaWorld November
2000 |
Get smart with proxies and
RMI - JavaWorld
November 2000
Get smart with proxies and
RMI - JavaWorld
November 2000 |
Retrofit existing
applications
with RMI - JavaWorld January 2001
Retrofit existing
applications
with RMI - JavaWorld January 2001 |
Servlets in Apache Tomcat and BEA Systems' WebLogic Server - JavaWorld February 2001
Servlets in Apache Tomcat and BEA Systems' WebLogic Server - JavaWorld February 2001 |
Exceptions: Don't
get thrown for a loss
Exceptions: Don't
get thrown for a loss |
Reinvented
wheel
Reinvented
wheel |
Sort it
out
Sort it
out |
Java Tip 134: When
catching exceptions, don't cast your net too wide
Java Tip 134: When
catching exceptions, don't cast your net too wide |
Protect Web
application
control flow
Protect Web
application
control flow |
Beware the dangers of
generic Exceptions
Beware the dangers of
generic Exceptions |
Clustering and Load Balancing in Tomcat 5, Part 2
Clustering and Load Balancing in Tomcat 5, Part 2 |
Quad Boot With Windows, Sun Java Desktop System, and the Solaris Operating System (Community-Submitted Article)
A BigAdmin reader describes to do a quad boot with Windows, two instances of the Sun Java Desktop System, and the Solaris 10 Operating System. |
Buy SuSe 9.1 Personal CDs in India from us. Suse 9.1 Personal is available with us.
Buy SuSe 9.1 Personal CDs in India from us. Suse 9.1 Personal is available with us.
SuSe 9.1 Personal Linux
Now Available SuSe 9.1 Personal CD's
SuSE 9.1 Personal Edition was based on the x86 port of the Personal Edition, and it includes all of |
VolatileBufferedToolkitImage Strategies
Ever wondered what kind of image to use in your application? Or what method to use in creating it? This article attempts to address this challenging topic. |
|
|
|