Exception Handling-checked or unchecked exceptions

Source: Internet
Author: User

Using checked exceptions exclusively leads to several problems:

Using checked exceptions may cause some problems:

  • Too much code

  • Too manyCode
    Developers will become frustrated by having to catch checked exceptions that they can't reasonably handle (of the "something when horribly wrong" variety) and write code that ignores (Swallows) them. agreed: This is indefensible coding practice, but experience shows that it happens more often than we like to think. even good programmers may occasionally forget to "nest" exceptions properly (more about this below), meaning that the full stack trace is lost, and the information contained in the exception is of bounded value.

  • Developers will feel very disappointed and have to catch the checked exception. They cannot handle it reasonably (when there are some terrible errors), and write code to ignore them. Agree: This is a non-rational code practice, but experience shows that it is beyond our imagination. Okay.ProgramThe employee may occasionally forget the "capture" exception attribute, which means that all stack records are lost and the information contained in the exception is simplified.

  • Unreadable code

  • Inaccessible code
    Catching exceptions that can't be appropriately handled and rethrowing them (wrapped in a different exception type) performs little useful function, yet can make it hard to find the code that actuallyDoesSomething. the orthodox view is that this bothers only lazy programmers, and that we shoshould simply ignore this problem. however, this ignores reality. for example, this issue was clearly considered by the designers of the core Java libraries. imagine the nightmare of having to work with collections interfaces suchJava. util. iteratorIf they threw checked, rather than unchecked, exceptions. the jdo api is another example of a sun API that uses unchecked exceptions. by contrast, JDBC, which uses checked exceptions, is cumbersome to work with directly.

  • Capture exceptions cannot be properly processed and rethrown (packaged in a different exception type) to execute a small number of useful functions. It may also make it difficult to find the actually executed code.

  • Endless wrapping of exceptions

  • Endless packaging exceptions
    A checked exception must be either caught or declared in the throws clause of a method that encounters it. this leaves a choice between rethrowing a growing number of conditions, or catching low-level conditions and rethrowing them wrapped in a new, higher-level exception. this is desirable if we add useful information by doing so. however, if the lower-level exception is unrecoverable, wrapping it achieves nothing. instead of an automatic IC unwinding of the Call Stack, as wocould have occurred with an unchecked exception, we will have an equivalent, manual, unwinding of the Call Stack, with several lines of additional, pointless, code in each class along the way. it was principally this issue that prompted me to rethink my attitude to exception handling.

  • A checked exception must be caught or declared in the throws clause of the method. This leaves a choice to re-throw a series of exceptions or capture low-level exceptions and then re-throw them into a new, more advanced exception. If I add useful information, this is very good. However, if a low-level exception cannot be recovered, it cannot be encapsulated. Instead, it is an automatic stack release call. As a result of an unchecked exception, we will have an equivalent, manual stack release call, with several additional lines in each class, meaningless code. This problem prompted me to correct my attitude towards exception handling.

  • Fragile method signatures

  • Fragile method Signature
    Once callers use a method, adding an additional checked exception to the interface will require encode code changes.

  • Once many callers continue with a method, adding an additional checked exception to the interface requires many code changes.

  • Checked exceptions don't always work well with Interfaces

  • the checked exception is not always suitable for interfaces
    take the example of the file system being full in the Java tutorial. this sounds OK if we're re talking about a class that we know works with the file system. what if we're dealing with an interface that merely promises to store data somewhere (maybe in a database )? We don't want to hardcode dependence on the Java I/O API into an interface that may be have different implementations. hence if we want to use checked exceptions, we must create a new, storage-agnostic, exception type for the interface and wrap file system exceptions in it. whether this is appropriate again depends on whether the exception is recoverable. if it isn't, we 've created unnecessary work.

  • I suggest the following guidelines for choosing between checked and unchecked exceptions:

    Question

    Example

    Recommendation if the answer is yes

    Shocould all callers handle this problem? Is the exception essential a second return value for the method?

  • Do all callers have to deal with this problem? An exception must have 2nd return values for this method?

    Spending limit exceeded inProcessinvoice ()Method

    Define and used a checked exception and take advantage of Java's compile-time support.

    Will only a minority of callers want to handle this problem?

  • Only a few callers need to solve this problem?

    JDO exceptions

    ExtendRuntimeexception. This leaves callers the choice of catching the exception, but doesn't force all callers to catch it.

    Did something go horribly wrong? Is the problem unrecoverable?

  • does this make things worse? Is this problem reachable?

    A business method fails because it can't connect to the application database

    extend runtimeexception . we know that callers can't do anything useful besides inform the user of the error.

    still not clear?

    extend runtimeexception . document the exceptions that may be thrown and let callers decide which, if any, they wish to catch.

One reason sometimes advanced for avoiding runtime exceptions is that an uncaught runtime exception will kill the current thread of execution. this is a valid argument in some situations, but it isn' t normally a problem in J2EE applications, as we seldom control threads, but leave this up to the application server. the application server will catch and handle runtime limits tions not caught in application code, rather than let them bubble up to the JVM. an uncaught runtime exception within the EJB container will cause the container to discard the current EJB instance. however, if the error is fatal, this usually makes sense.

An important reason to avoid runtime exceptions is that uncaptured runtime exceptions will kill the execution of the current thread. In some cases, this is an effective argument, but this is usually not a problem in J2EE applications, because we seldom control the thread and leave it to the top of the application server. The Application Server captures and processes runtime exceptions that are not captured in the Code, rather than letting them arrive at the JVM. An uncaptured runtime exception will cause the container to discard the current EJB instance in the EJB container. However, errors are often meaningful if they are fatal.

Good exception handling practices

Good exception practices

Whether we used checked or unchecked exceptions, we'll still need to address the issue of "nesting" exceptions. typically this happens when we're re forced to catch a checked exception we can't deal with, but want to rethrow it, respecting the interface of the current method. this means that we must wrap the original, "nested" exception within a new exception.

Whether to use the checked or unchecked exception. We still need to solve the "nested" exception problem. This usually happens when we are forced to capture a checked exception that we cannot handle, but we want to throw it again, for the interface of the current method. This means that we must wrap the original "nested" exception in a new exception.

Some standard library exceptions, suchJavax. servlet. servletexception, Offer such wrapping functionality. but for our own application exceptions, we'll need to define (or use existing) custom exception superclasses that take a "Root Cause" exception as a constructor argument, expose it to code that requires it, and overridePrintstacktrace ()Methods to show the full stack trace, including that of the root cause. Typically we need two such base exceptions, one for checked and on for unchecked exceptions.

Some standard library exceptions, such as javax. servlet. servletexception, provide such packaging functions. However, for exceptions of my own applications, we need to define (or use existing) Customized exception parent classes and take a "root" exception as the constructor parameter, expose it to the required encoding. Rewrite the printstacktrace () method to show all stack traces, including this root cause. We usually need such a base class exception. One is checked and the other is unckecked.

Note

Note:

This is no longer necessary in Java 1.4, which supports exception nesting for all exceptions. We'll discuss this important enhancement below.

This is not necessary in java1.4. It supports nesting exceptions in all exceptions. We will discuss this important enhancement below.

In the generic infrastructure code accompanying our sample application, the respective classes areCom. interface21.core. nestedcheckedexceptionAndCom. interface21.core. nestedruntimeexception. Apart from being derived fromJava. Lang. ExceptionAndJava. Lang. runtimeexceptionRespectively, these classes are almost identical. Both these exceptions are abstract classes; only subtypes have meaning to an application. The following is a complete listingNestedruntimeexception:

With our simple application in common infrastructure Code, these two classes areCom. interface21.core. nestedcheckedexceptionAndCom. interface21.core. nestedruntimeexception.Java. Lang. ExceptionAndDerived from Java. Lang. runtimeexception, these classes are almost the same. These two classes are all abstract classes; only child types are meaningful to applications. Below is a completeNestedruntimeexception list:

 Package Com. interface21.core;

Import Java. Io. printstream;
Import Java. Io. printwriter;

Public Abstract Class Nestedruntimeexception Extends Runtimeexception {

Private Throwable rootcause;

Public Nestedruntimeexception (string s ){
Super (S );
}

Public Nestedruntimeexception (string S, throwable ex ){
Super (S );
Rootcause = ex;
}

Public Throwable getrootcause (){
Return Rootcause;
} Public String getmessage (){
If (Rootcause = NULL ){
Return Super . Getmessage ();
} Else {
Return Super . Getmessage () + "; Nested exception is: \ n \ t" +
Rootcause. tostring ();
}
} Public Void Printstacktrace (printstream PS ){
If (Rootcause = NULL ){
Super . Printstacktrace (PS );
} Else {
PS. println ( This );
Rootcause. printstacktrace (PS );
}
}

Public Void Printstacktrace (printwriter PW ){
If (Rootcause = NULL ){
Super . Printstacktrace (PW );
} Else {
PW. println ( This );
Rootcause. printstacktrace (PW );
}
}

Public Void Printstacktrace (){
Printstacktrace (system. Err );
}
}

 
 

Java 1.4 introduces welcome improvements in the area of exception handling. there is no longer any need for writing chainable exceptions, although existing infrastructure classes like those shown above will continue to work without a problem. new constructors are addedJava. Lang. throwableAndJava. Lang. ExceptionTo support chaining, and a new methodVoid initcause (throwable T)Is addedJava. Lang. throwableTo allow a root cause to be specified even after exception construction. This method may be invoked only once, and only if no nested exception is provided in the constructor.

Java1.4 introduced the welcome changes in the exception handling area. There is no need to write a connectable exception, even if there is a basic class as shown above, it will continue to work without any problem. The new constructor is added

Java. Lang. throwableAndJava. Lang. ExceptionTo support chain processing, a new methodVoid initcause (throwable T) is addedJava. Lang. throwableYou can specify the root cause even after the exception is constructed. This method may be called only once. If nested exceptions are provided in the constructor method.

Java 1.4-aware exceptions shocould implement a constructor taking a throwable nested exception and invoking the newExceptionConstructor. This means that we can always create and throw them in a single line of code as follows:

In java1.4, realize that an exception must implement a constructor as a nested exception that can be thrown and call this new constructor. This means that we can always create and then throw them in several lines of code, like the following:

Catch(Rootcauseexception ex ){
Throw NewMyjava14exception ("Detailed message", Ex );
}

If an exception does not provide such a constructor (for example, because it was written for a Pre Java 1.4 environment ), we are guaranteed to be able to set a nested exception using a little more code, as follows:

If an exception does not provide such a constructor (for example, because it was written for the Environment earlier than java1.4), make sure that a nested exception may be set with a little more code, as shown below:

 
Catch(Rootcauseexception ex ){
Myjava13exception Mex =NewMyjava13exception ("Detailed message");
Mex. initcause (Ex );
ThrowMex;
}

When using nested Exception Solutions such as nestedruntimeexception, discussed above, follow their own conventions, rather than Java 1.4 Conventions, to ensure correct behavior.

When nested Exception Solutions such as nestedruntimeexception are used, as discussed above, follow your own conventions instead of Java 1.4 specifications to ensure correct behavior.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.