Java Theory and Practice: About Unusual Argument

xiaoxiao2021-03-06  42

Similar to C , Java language also provides abnormal throwing and capture. However, with C is that Java language supports inspection and non-checking exceptions. The Java class must declare any of the inspected exceptions thrown in the method signature, and for any method, if it calls the method throws a type E, it must be captured or declared as a throw E (or a parent class). In this way, the language enforces our documentation control may exit all expected ways of a method.

For exceptions caused by programming errors, or not to expect an exception captured by the program (release a null pointer, array, division, etc.), in order to prevent the developer from handling these abnormalities, some abnormalities are named Check an exception (ie those who inherit from RuntimeException) and do not need to be declared.

Traditional view

In the excerpt from Sun's "The Java Tutorial", summarize traditional perspectives about the abnormality declaration as an inspection or non-check type (more information):

Because the Java language does not require methods to capture or specify runtime exceptions, write only the code that only throws running time is or makes all of them inheritable from RuntimeException, which is attractive for programmers. These programming shortcuts allow programmers to write Java code without being disturbed from all pick-up errors from the compiler, and do not have to specify or capture any exceptions. Although this seems to be more convenient for programmers, it avoids Java capture or designated intentions, and for programmers who use the class you can lead to problems.

The inspection-type exception represents useful information about the operation of a legally specified request, the caller may have not controlled the operation, and the caller needs to be relevant notifications - for example, the file system is full, or the remote is closed, or the remote connection is closed. Or access to this action is not allowed.

If you just throw a runtimeException, or create a subclass of RuntimeException, then have you changed? You just got an abnormality that throw an exception without having to specify this. In other words, this is a way to avoid an abnormality that the documentation method can be thrown. When is this beneficial? That is, when is it possible to avoid the behavior of a method? The answer is "almost never."

In other words, SUN tells us that the inspection of an exception should be a guideline. The tutorials continue to explain in a variety of ways, usually should be thrown instead of runtimeexception - unless you are JVM.

In Effective Java: Programming Language Guide (see Resources), Josh Bloch provides the following knowledge points about check-type and non-inspected exceptions, which are consistent with the recommendations in The Java Tutorial (but not It is completely strict):

Article 39: Only for abnormal conditions. That is, do not use an exception for the control flow, for example, capture NosuchelementException when calling iterator.next () during the first check of item.hasNext ().

Article 40: Use an inspection-type exception to recoverable conditions to use the running time of programming errors. Here, Bloch responds to traditional Sun views - running abnormalities should only be used to indicate programming errors, such as violating preamp. Article 41: Avoid unnecessary use inspection types. In other words, the case where the caller cannot recover from it, or the only foreseeable response will be the program exit, do not use the check-type exception.

Article 43: Throw an abnormality that is adapted to abstract. In other words, the exception thrown by a method should be defined at an abstraction level, which is consistent with the method, and does not necessarily consistent with the underlying implementation of the method. For example, a method from files, databases, or JNDI load resources should throw some resourceNotFound anomalies when they cannot find resources (usually using an exception chain to save implicit), not a more underlying IOException, SQLException, or Namingexception.

Re-examine the orthodox point of non-examination

Recently, several respected experts, including Bruce Eckel and Rod Johnson, have disclosed despite their initial intention of the orthodox point of examination, but they have already identified exclusive use of inspection-type unusual ideas and did not initially look like it. And for many large projects, inspection-type abnormalities have become an important source. Eckel proposes a more extreme view, it is recommended that all exceptions should be non-inspected; Johnson's point of view is conservative, but still implies that traditional priority selection is excessive. (It is worth mentioning that the C # designer chooses to ignore the inspection exception in language design, making all anomalies are non-inspected, so they can affirm their experience in Java technology. However, they did check it later. The realization of an abnormality has left space.)

Some criticisms of check-type exceptions

ECKEL and JOHNSON pointed out a list of similar issues on check-type unusual; some are intrinsic properties of inspection-type exceptions, and some are the properties of the specific implementation of the inspection exception in the Java language, and some are simply observations, mainly It is a wide range of error uses to be a serious problem that causes the mechanism to be reconsidered.

Check-type unusual exposure implementation details

How many times you have seen (or write) a way to throw SQLEXCEPTION or IOException, even if it looks uncomfortable with the database or file? For developers, all exceptions that may be thrown in one way are summarized in the initial implementation of a method and increase them to the method's ThROWS clause (many IDEs even helping you to do this task) are very common. One problem with this direct method is that it violates the abnormality of paragraph 43 of Bloch - the abnormality lying on the abnormality is inconsistent with the method of throwing them.

A method for loading a user profile, should throw NosuchuseRexception when not finding the user, not the SQLException - the caller can make it good to the user may not find, but do not know how to handle SQLException. The abnormal chain can be used to throw a more appropriate exception without discarding details about the underlying failure (such as stack tracking), allowing the abstraction layer to be separated from the layered detail below them. Come, while retaining information that may be useful for debugging.

It is said that the design of the JDBC package takes a way that it is difficult to avoid this problem. Each method in the JDBC interface throws SQLException, but in the process of accessing a database, there may be a variety of different types of problems, and different methods may vulnerable to different error modes. A SQLException may indicate a system-level issue (not connected to the database), the logic problem (there is no more rows in the result set) or a specific data problem (you just try to insert the primary key that exists or violates the entity integrity). If there is no unforgivable attempt to analyze the negligence of the text body, the caller is impossible to distinguish these different types of SQLException. (SQLEXCeption is indeed a way to obtain database specific error codes and SQL status variables, but these are rarely used in practice different database error conditions.) Unstable method signature

Unstable method Signature problem is related to the previous problem - if you only pass an exception through a method, then you have to change its method signature when you change the method, and change all of the code to call the method. Once the class has been deployed to the product, managing these fragile methods will become an expensive task. However, this problem is essentially another symptom of Article 43 of Bloch. Methods should throw an exception when encounter failure, but this exception should reflect what the method does, not what it does.

Sometimes, when the programmer is bored from the method signature, when the change is bored from the method signature, they are not bored by using an abstraction to define the possible type of exception, but only all the methods are declared. To throw an Exception. In other words, they have already identified an exception only leads to trouble and basically shuts it off. Needless to say, this method is usually not a good error handling policy for most of the most useful code.

Understanding code

Because many methods throw a certain number of different abnormalities, the error handling code may be as high as the actual functional code, so that it is difficult to find a code that actually completed the function in a method. An exception is a way to reduce the code by centralized error handling, but a method with three lines of code and six catch blocks (where each block is only recorded or packaged, and the exception is re-thrown) looks more expanded and makes it Simple code becomes blurred.

Abnormally

We have seen such a code, which captures an exception, but there is no code in the Catch block. Although this programming practice is obviously bad, it is easy to see how it happens - during prototyping, someone packs code through the Try ... Catch block, and then forgets to return and fill the Catch block. Although this mistake is very common, this is also better tools to help us with one of our places - for an abnormal place, can easily detect and issue a warning through editor, compiler, or static check tool.

Extremely universal Try ... catch block is another form of abnormal submergence and more difficult to detect because this is caused by the structure of the anomalous class hierarchy in the Java class library (suspicious). Let us assume that one method throws four different types of exceptions, and the caller encounters any of these exceptions, records them, and returns. One way to achieve this strategy is to use a Try ... Catch block with four CATCH clauses, each of which is one. In order to avoid problems that code is difficult to understand, some developers will refactor the code, such as Listing 1:

Listing 1. Unexpectedly submerge RuntimeException

Try {

DOSMETHING ();

}

Catch (Exception E) {

Log (e);

}

Although the code is compact than four CATCH blocks, it has a problem - it also captures any runtimeException that may be thrown by DOSMETHING and prevents them from spreading. Excessive unusual packaging

If an exception is generated in a bottom facility and diffuses upward through many code layers, it may be captured, packaged, and re-throw several times prior to eventually being processed. When an exception is finally recorded, the stack tracking may have many pages, because the stack tracking may be copied multiple times, each of which is once. (In JDK 1.4 and later versions, the implementation of the abnormal chain is alleviated to some extent.)

Replacement method

The author of Bruce Eckel, Thinking In Java, claims that after many years of using Java languages, it has been concluded that the examination is an error - a test that should be declared as a failure. ECKEL advocates all anomalies as a non-check-type, and provides a method in Listing 2 as a method that converts the inspection-type abnormality into a non-check-type exception, while retaining a particular type of abnormality when an exception is spreading upward from the stack. Ability (for explanation of how to use this method, please refer to the article he in the reference information section):

Listing 2. ECKEL's exception adapter

Class ExceptionAdapter Extends RuntimeException {

PRIVATE FINAL STRINGTACKTRACE;

Public Exception OriginalException;

Public ExceptionAdapter (Exception E) {

Super (e.tostring ());

OriginalException = E;

StringWriter SW = new stringwriter ();

E.PrintStackTrace (New PrintWriter (SW));

StackTrace = SW.TOSTRING ();

}

Public void printstacktrace () {

PRINTSTACKTRACE (SYSTEM.ERR);

}

Public void printstacktrace (java.io.printStream S) {

SYNCHRONIZED (s) {

s.print (getClass (). getName () ":");

S.print (stacktrace);

}

}

Public void PrintStackTrace (java.io.printwriter s) {

SYNCHRONIZED (s) {

s.print (getClass (). getName () ":");

S.print (stacktrace);

}

}

Public void Rethrow () {throw OriginalException;

}

If you look at the discussion on the Eckel's Web site, you will find that the response is severely split. Some people think that his proposal is ridiculous; some people think this is an important idea. (My point is that although it is really difficult to use it properly, and the exception is in a large number of exquisite examples, most of them agree with him because of the wrong reason, this is in relation to a politician A number of counsels that can be taken from the top of the chocolate will be similar to the situation of a large number of votes for the ten-year-old children.)

Rod Johnson is the author of J2EE DESIGN AND Development (see Resources), which is one of the best books I have read about Java development, J2EE and other aspects. He takes a less radical approach. He lists multiple categories of abnormalities and determines a policy for each category. Some abnormalities are essentially a secondary return code (which usually indicates violations of business rules), and some abnormal variants "have a terrible error" (such as database connection failure). Johnson advocates the use of check-type exceptions for the first category of exceptions (optional return code), and the latter uses running time. In the category of "a terrible error", its motivation is simply recognized that no caller can effectively handle the exception, so it may also be spread along the stack in various ways and maintain the minimum of the intermediate code. (And minimize the possibility of abnormal submerged). Johnson also enumerates an intermediate situation, and it is a problem for this, "Just a few caller wants to handle the problem?" For these cases, he also recommended that non-inspected exceptions. As an example of this category, he lists the JDO abnormality - in most cases, the case where the JDO abnormal representation is that the caller does not want to handle, but in some cases, it is useful to capture and handle specific types of exceptions. He suggests that the non-inspected exception is used here, rather than letting the rest of the use of JDO classes to make up for this possibility by capturing and re-throwing these exceptions.

Using non-inspected abnormalities

The decision on whether to use non-inspected anomalies is complicated, and it is apparent that there is no obvious answer. Sun's suggestion is to use them anything, while C # methods (that is, ECKEL and others) are not used for any situation. Others say, "there is still a middle situation."

By using exceptions in C , all of them are non-inspected. One of the biggest risks that I have found that non-inspected anomalies are not as self-documentation as in the way inspected exceptions. Unless the API's creator explicitly documentation will throw an exception, the caller has no way to know what the exception to capture in their code. Unfortunately, my experience is very poor in most C APIs, and even if the documentation is very good API lacks sufficient information about the abnormality that may thrown from a given method. I can't see any reason can be said that the problem is not the same for the Java class library, because JAV libraries are seriously dependent on non-checking exceptions. It is very difficult to depends on your own or your partner's programming skills; if you have to rely on someone's documentation skills, then you may have to use sixteen frames in the call stack as you. The main error handling mechanism, which will be panicked.

Documentation issues further emphasize why lazy is a bad reason that causes the use of non-inspected anomalies, because the burden on the package is added to the package, using non-checking exceptions should be more than using inspections and even higher (when documentation The non-checking exception you thrown is more important than the inspection-type abnormality).

Documentation, documentation, documentation

If you decide to use a non-inspected exception, you need to thoroughly document this choice, including all non-inspected exceptions that may thrown in Javadoc Chinese filemill. Johnson recommends selecting check and non-checking exceptions on the basis of each package. Remember when using non-inspected anomalies, even if you don't capture any exceptions, you may need to use the try ... finally block, so that the cleaning action can be performed such as shutting down the database connection. For check-type exceptions, we have TRY ... catch to prompt to add a finally clause. For non-checking exceptions, we don't have this support.

转载请注明原文地址:https://www.9cbs.com/read-74921.html

New Post(0)