Java_ Abnormal handling Error

Source: Internet
Author: User
Tags throwable

Transferred from: https://www.ibm.com/developerworks/cn/java/j-lo-exception-misdirection/index.html

This article emphatically introduced the Java exception choice and the use of some misunderstandings, I hope you can master the exception handling some of the points of attention and principles, pay attention to summary and induction. Only when the exception is handled, can we improve the basic literacy of the developers, improve the robustness of the system, enhance the user experience and improve the value of the product.

Myth One: The choice of the exception

We all know anomaly detection anomaly and non-detection anomaly, but in practice it confuses the application of these two kinds of anomalies. Because of the ease of use of non-detection anomalies, many developers consider it useless to detect anomalies. In fact, abnormal application scenarios can be summarized as follows:

One, the calling code cannot continue execution and needs to be terminated immediately . There are too many possibilities for this, such as server connections, incorrect parameters, and so on. This applies to non-detection exceptions, does not require explicit capture and processing of the calling code, and the code is straightforward.

Second, the calling code needs to be further processed and resumed . If SQLException is defined as a non-detection exception, the developer takes the data for granted that the SQLException does not require explicit capture and processing of the calling code, which in turn leads to serious Connection not shutting down, Transaction not rolling back, DB such as dirty data in the SQLException is defined as a detection exception that drives the developer to explicitly capture and cleans up resources after the code generates an exception. Of course, after cleaning up the resources, you can continue to throw non-detection exceptions to prevent the execution of the program. Based on observation and understanding, detection anomalies can be applied to tool classes in most cases.

Misunderstanding two, the exception is displayed directly on the page or client.

The example of printing an exception directly on the client is common, with JSP as an example, and by default the container prints the exception stack information directly on the page, once the code is running abnormally. In fact, from the customer's point of view, any exception has no practical significance, the vast majority of customers also do not understand the abnormal information, software development should try to avoid the exception directly to the user.

 Packagecom.ibm.dw.sample.exception;/*** Custom RuntimeException * Add error code Properties*/ Public classRuntimeExceptionextendsjava.lang.RuntimeException {//default error code     Public Static FinalInteger GENERIC = 1000000; //Error code    PrivateInteger ErrorCode;  Publicruntimeexception (Integer errorCode, throwable cause) { This(ErrorCode,NULL, cause); }      Publicruntimeexception (String message, throwable cause) {//using common error codes             This(GENERIC, message, cause); }      Publicruntimeexception (Integer errorCode, String message, Throwable cause) {Super(message, cause);  This. ErrorCode =ErrorCode; }      PublicInteger GetErrorCode () {returnErrorCode; } }

As the sample code shows, introducing an error code into the exception, once an exception occurs, we simply present the exception's error code to the user, or convert the error code to a more understandable hint. In fact, the error code here also contains another function, the developer can also be based on the error code to know exactly what type of exception occurred.

Misunderstanding three, the pollution of the Code hierarchy structure

We often divide the code into different hierarchies, such as Service, Business Logic, and DAO, and the DAO layer contains methods for throwing exceptions, as shown in Listing 2:

  

 Public Throw  // query database by ID }

The above code is not a problem at first glance, but from the design coupling point of view, here the SQLException pollution to the upper calling code, the call layer needs to explicitly use the Try-catch capture, or further to the upper layer of the throw. Based on the design isolation principle, we can modify it appropriately:

 Public Customer Retrievecustomerbyid (Long id) {     try{            // query database by ID     } Catch (SQLException e) {            // use non-detection exception encapsulation to detect anomalies, reduce level coupling            throwNew  runtimeexception (Sqlerrorcode, E);     } finally {            // close connection, clean resource      }}
Misunderstanding four, ignoring exceptions

The exception handling below simply outputs the exception to the console, without any meaning. And there's an exception here that doesn't interrupt the program, and the calling code continues execution, causing more exceptions.

 Public void Retrieveobjectbyid (Long id) {   try{       //... Some code that throws SQLException    }catch(SQLException ex) {     /**        * Everyone knows that abnormal printing here is meaningless, just outputting the error stack to the console.       * In the Production environment, the error stack needs to be output to the log.       * And after the catch is processed, the program continues to execute, causing further problems */                   ex.printstacktrace ();     }}

Can be re-formed:

 Public void  Try{    //... Some code that throws SQLExceptioncatch(SQLException ex) {    throw New  finally{    //clean upresultset, statement, connection etc  }}
Error five, the exception is included in the Loop statement block (this misunderstanding is relatively basic, generally do not make this low-level error)

The exception is included in the For Loop statement block, as shown in the following code.

 for (int i=0; i<100; i++) {    try{    }catch(Xxxexception e) {          //  ....     }}

We all know that exception handling consumes system resources. At first glance, we all think we will not make such a mistake. At a different angle, a loop is executed in class A, and the method of Class B is called, and the method called in Class B contains a block of statements such as Try-catch. Fade the hierarchy of classes, and the code is the same as above.

Misunderstanding six, using Exception to capture all potential anomalies

Several different types of exceptions are thrown during a method execution, and for the sake of brevity, the base class Exception captures all potential exceptions, as shown in the following example:

 Public void Retrieveobjectbyid (Long id) {    try{        //... Throw IOException code Call         //... Throw SQLException code call    }catch(Exception e) {        // use base class here Exception captures all potential exceptions, and if multiple levels are captured like this, the valid information for the original exception is lost ,        thrownew  runtimeexception (" Exception in Retieveobjectbyid ", e);    }}

Can be re-formed

 Public voidRetrieveobjectbyid (Long id) {Try{        //.. Some code that throws RuntimeException, IOException, SQLException}Catch(IOException e) {//just capture IOException .        Throw NewRuntimeException (/*Specify the error code corresponding to this IOException*/code, "Exception in Retieveobjectbyid", e); }Catch(SQLException e) {//just capture SQLException .        Throw NewRuntimeException (/*Specify the error code corresponding to this SQLException*/code, "Exception in Retieveobjectbyid", e); }}
Error seven, multi-level encapsulation throws non-detection exception

If we keep insisting that different types of exceptions must use different capture statements, then most of the examples can bypass this section. However, if a single code call throws more than one exception, it is often not necessary to write a catch statement for each of the different types of Exception, and for development, any exception is sufficient to illustrate the specific problem of the program.

 try  { / /  may throw runtimeexception, ioexeption, or other;  / /  Note here and the misunderstanding six difference, here is a piece of code throws a variety of exceptions.    The above is a multi-segment code, each throws a different exception }catch   (Exception e) {  //  As always, convert Exception to RuntimeException, But here the E is actually an instance of RuntimeException, already encapsulated in the previous code  throw  new  runtimeexception (/**  /code,/*  */  

If we convert all the Exception to RuntimeException as shown in the example above, then when the Exception type is already runtimeexception, we do a package again. The runtimeexception was re-encapsulated once, thus losing the valid information that the original runtimeexception carried.

The workaround is that we can add the relevant checks in the RuntimeException class to confirm that the parameter throwable is not an instance of RuntimeException. If it is, the corresponding property is copied to the newly created instance. or capture RuntimeException and other Exception with different catch statement blocks. Personal Preference Mode One, the benefits are self-evident.

Misunderstanding eight, multi-level printing anomalies

Let's take a look at the following example, which defines 2 classes A and B. Where Class A calls the code for Class B, and the Class A and Class B catch print exceptions.

 Public classA {Private StaticLogger Logger = Loggerfactory.getlogger (A.class);  Public voidprocess () {Try{     //Instantiate class B, can be replaced by other injection methodsb b =NewB ();     B.process (); //Other code might cause exception}Catch(xxxexception e) {//if the class B process method throws an exception, the exception will be printed in class B, where it will be printed, which will print 2 timesLogger.error (e); Throw NewRuntimeException (/*Error code*/ErrorCode,/*Exception Information*/msg, E); }    }} Public classb{Private StaticLogger Logger = Loggerfactory.getlogger (B.class);  Public voidprocess () {Try{            //code that could throw an exception        }        Catch(xxxexception e) {logger.error (e); Throw NewRuntimeException (/*Error code*/ErrorCode,/*Exception Information*/msg, E); } }}

  

The same exception will be printed 2 times. If the level is a little more complicated, not to consider the performance of the print log consumption of the system, only in the Exception log to locate the exception specific problems have enough headaches.

In fact, the print log only needs to capture print on the outermost layer of the Code, and exception printing can also be written as AOP, woven into the outermost layer of the frame.

Misunderstanding nine, the information contained in the exception can not adequately locate the problem

Exceptions not only allow developers to know what is wrong, but more often developers need to know what causes the problem, and we know java. lang. Exception has a constructor method for string type parameters, which can be customized to be easily understandable.

Simple custom information developers can only know where an exception has occurred, but in many cases, developers need to know what parameters are causing such an exception. At this point we need to append the parameter information of the method invocation to the custom information. The following example only lists the case of a parameter, where multiple parameters can be written in a single tool class to organize such a string.

 Public void Retieveobjectbyid (Long id) {    try{        //... Some code that throws SQLException   }catch(SQLException ex) {        //  Add parameter information to exception information        thrownew runtimeexception ("Exception in Retieveobjectbyid with Object ID: "+ ID, ex);}   }
Error ten, can not predict the potential anomalies

In the process of writing code, because of the lack of a deep understanding of the calling code, it is not possible to accurately determine whether the calling code produces an exception and therefore ignores processing. After the Production Bug is created, you should add an exception catch at a certain code point and not even pinpoint the cause of the exception.  This requires the developer not only to know what they are doing, but also to know as much as possible what others have done, what results may result, and to consider the whole process of the application from the global. These ideas can affect the writing and processing of our code.

Misunderstanding Xi. mixed use of a variety of third-party log libraries

Today there are more and more types of third-party log libraries in Java, and a large project introduces a variety of frameworks that rely on the implementation of different log libraries. The most troublesome problem is not the introduction of all the required log libraries, the problem is that the imported log libraries are inherently incompatible. If this is possible at the beginning of the project, you can re-introduce all the log libraries in your code as needed, or change the framework. But such costs are not borne by each project, and the greater the risk is as the project progresses.

How to effectively avoid similar problems, most of the current framework has taken into account a similar problem, you can configure the Properties or XML files, parameters, or run-time scanning Lib Library of the log implementation class, really in the application run time to determine the specific application of the specific log library.

In fact, based on the principle of not requiring a multi-level print log, we can simplify many of the classes that originally called the Log Print code. In many cases, we can use interceptors or filters to achieve log printing, reducing the cost of code maintenance and migration.

Java_ Abnormal handling Error

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.