Java Theory and Practice: exception debate

Source: Internet
Author: User

Similar to C ++, Java also provides exception throws and capturing. However, unlike C ++, Java supports checked and non-checked exceptions. Java classes must declare any checked exceptions they throw in the method signature, and if any method is called, if it throws a checked exception of Type E, then it must capture E or declare it to throw E (or a parent class of E ). In this way, the language forces us to document all the expected methods that may exit a method.

For exceptions caused by programming errors, or exceptions that cannot be captured by the Program (removing the reference of a null pointer, array out-of-bounds, Division by zero, etc ), to prevent developers from handling these exceptions, some exceptions are named as non-check‑type exceptions (Exceptions inherited from RuntimeException) and do not need to be declared.

Traditional Viewpoint
In The following excerpt from Sun's "The Java Tutorial, summarizes the traditional ideas about declaring an exception as a checked or non-checked type (for more information, see references ):

Because Java does not require methods to capture or Specify runtime exceptions, writing code that throws only runtime exceptions or makes all of their exception subclasses inherit from RuntimeException, it is attractive for programmers. These programming shortcuts allow programmers to write Java code without being disturbed by all picky errors from the compiler and without specifying or capturing any exceptions. Although this seems convenient for programmers, it bypasses Java capture or specifies the intent of the request, and may cause problems for programmers who use the class you provide.

A Checkpoint exception indicates useful information about the operation of a specified legal request. The caller may have no control over the operation and the caller needs to receive related notifications ?? For example, the file system is full, the remote connection has been closed, or the access permission does not allow this action.

If you only throw a RuntimeException because you do not want to specify an exception or create a subclass of RuntimeException, what do you get? You only get the ability to throw an exception without specifying it. In other words, this is a way to avoid exceptions thrown by documented methods. When is this beneficial? That is to say, when can it be helpful to avoid specifying a method? The answer is "almost never ."

In other words, Sun tells us that a checked exception should be a criterion. This tutorial continues to explain in multiple ways. An exception should be thrown instead of a RuntimeException ?? Unless you are a JVM.

In objective Java: Programming Language Guide (see references), Josh Bloch provides the following knowledge about checked and non-checked exceptions, these are The same as The suggestions in The "The Java Tutorial" (but not exactly The same ):

Article 39th: exception is only applicable to abnormal conditions. That is to say, do not use exceptions for the control flow. For example, NoSuchElementException is captured when Iterator. next () is called rather than when Iterator. hasNext () is checked for the first time.
Article 40th: checktype exceptions can be used for recoverable conditions, and runtime exceptions are used for programming errors. Here, Bloch responds to the traditional Sun viewpoint ?? Runtime exceptions should only be used to indicate programming errors, such as violation of preconditions.
Article 41st: Avoid unnecessary inspection exceptions. In other words, do not use a check exception if the caller cannot recover from it, or the only foreseeable response will be program exit.
Article 3: throws an exception that matches the abstraction. In other words, the exception thrown by a method should be defined at an abstract level, which is consistent with what the method is, not necessarily with the underlying implementation details of the method. For example, a method for loading resources from a file, database, or JNDI should throw a ResourceNotFound exception when the resource cannot be found (the exception chain is usually used to save the implicit cause ), instead of the underlying IOException, SQLException, or NamingException.
Review the orthodox view of non-checked exceptions
Recently, several distinguished experts, including Bruce Eckel and Rod Johnson, have publicly stated that although they initially fully agree with the orthodox view of checked exceptions, however, they have determined that the idea of exclusive use of checked exceptions is not as good as originally, and for many large projects, checked exceptions have become an important source of problems. Eckel proposed a more extreme view, suggesting that all exceptions should be non-check‑type; Johnson's view should be conservative, but it still implies that the traditional priority check-type exceptions are too much. (It is worth mentioning that the C # designer chooses to ignore checked exceptions in the language design so that all exceptions are non-checked, therefore, it is almost certain that they have rich Java technology experience. However, they did leave room for the implementation of checked exceptions .)

Some criticisms of checked exceptions
Both Eckel and Johnson have pointed out a list of similar issues about checked exceptions. Some are internal attributes of checked exceptions and some are attributes of specific implementations of checked exceptions in Java, there are also some simple observations, mainly about how the wide range of incorrect use of checked exceptions becomes a serious problem, which may cause this mechanism to be reconsidered.

Check type exception does not properly expose Implementation Details
How many times have you seen (or written) a method that throws SQLException or IOException, even if it looks unrelated to the database or file? For developers, summarize all exceptions that may be thrown in the initial implementation of a method and add them to the throws clause of the method (many ides even help you execute this task) is very common. One problem with this direct method is that it violates the 43rd ?? The abstraction level of thrown exceptions is inconsistent with that of the methods that throw them.

A method used to load the user summary should throw NoSuchUserException instead of SQLException ?? The caller can predict that the user may not be able to find it, but does not know how to handle SQLException. Exception chains can be used to throw a more appropriate exception without discarding details about underlying failures (such as stack tracking ), the abstraction layer is allowed to isolate the layers above them from the details of the layers under them, while retaining information that may be useful for debugging.

It is said that the JDBC package is designed in such a way that it is difficult to avoid this problem. Every method in the JDBC interface throws SQLException. However, when accessing a database, different types of problems may occur, and different methods may be vulnerable to different error modes. A SQLException may indicate a system-level problem (cannot connect to the database) and a logic problem (no more rows in the result set) or a specific data issue (the primary key of the row you just attempted to insert already exists or violates the entity integrity constraints ). Without an irrevocable attempt to analyze the message body, it is impossible for callers to distinguish these different types of SQLException. (SQLException does support methods used to obtain database-specific error codes and SQL state variables. However, in practice, these methods are rarely used to differentiate different database error conditions .)

Unstable method Signature
The unstable method signature issue is related to the previous issue ?? If you only pass an exception through a method, you have to change the method signature and change all the code that calls the method each time you change the implementation of the method. Once the class has been deployed in the product, managing these fragile method signatures becomes an expensive task. However, this problem is essentially another symptom that does not follow the 43rd articles proposed by Bloch. When a method fails, an exception should be thrown, but the exception should reflect what the method does, rather than how it does it.

Sometimes, when programmers get bored with adding or deleting exceptions in method signatures due to implementation changes, they do not define the types of exceptions that may be thrown at a specific level by using an abstraction, instead, they declare all their methods as throwing an Exception. In other words, they have determined that exceptions only cause troubles and basically shut them down. Needless to say, this method is generally not a good error handling policy for the vast majority of code that can be used at will.

Obscure code
Because many methods throw a certain number of different exceptions, the ratio of error handling code to the actual functional code may be high, making it difficult to find the code that actually completes the function in a method. Exceptions are reduced by centralized error handling, but one has three lines of code and six catch blocks (each of which only records exceptions or wraps and throws exceptions again) the method seems to be relatively inflated and will blur the original simple code.

Exception flood
We have seen such code, and an exception is caught, but there is no code in the catch Block. Although this programming practice is obviously not good, it is easy to see how it happened ?? During prototype, someone wraps the Code through the try... catch Block, and then forgets to return and fill in the catch Block. Although this error is common, it is also a better tool to help us ?? The editor, compiler, or static check tool can easily detect and issue warnings when exceptions are drowned.

The extremely common try... catch Block is another form of exception flooding and is more difficult to detect because it is caused by the abnormal class hierarchy in the Java class library (suspicious ). Let's assume that a method throws four different types of exceptions, and the caller will capture and record any of these exceptions and return them. One way to implement this policy is to use a try... catch Block with four catch clauses, with one exception type. To avoid issues that are hard to understand, some developers will refactor the code, as shown in Listing 1:

Listing 1. Accidentally overwriting RuntimeException


Try {
DoSomething ();
}
Catch (Exception e ){
Log (e );
}


Even though this code works with four & nb

Related Article

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.