Java-exception Practice

Source: Internet
Author: User

Handling Exceptions in Java is not a simple matter. Not only is it difficult for beginners to understand, even some experienced developers spend a lot of time thinking about how to handle exceptions, including what exceptions to handle, how to handle them, and so on. This is the reason most development teams develop rules that govern the handling of exceptions. These specifications are often quite different between the teams.

This article gives several exception handling best practices that are used by many teams.

1. Clean up resources in the finally block or use the Try-with-resource statement

When using a resource similar to inputstream that needs to be closed after use, a common mistake is to close the resource at the end of the try block.

1234567891011121314  
public void doNotCloseResourceInTry() {    FileInputStream inputStream = null;    try {        File file = new File("./tmp.txt"); inputStream = new FileInputStream(file); // use the inputStream to read a file // do NOT do this inputStream.close(); } catch (FileNotFoundException e) { log.error(e); } catch (IOException e) { log.error(e); }}

The above code is not a problem to run without any exception. However, when the statement in the try block throws an exception or the code that implements it itself throws an exception, the last closing statement is not executed and the resource is not freed.

It is reasonable to put all the cleaned code in the finally block or use the Try-with-resource statement.

12345< Span class= "Line-number" >6789< Span class= "Line-number" >10111213 141516 17181920 212223 24252627 2829           
public void closeresourceinfinally () {FileInputStream inputstream = null;try {File File = new file ("./tmp.txt");InputStream = new FileInputStream (file);Use the InputStream to read a file} catch (FileNotFoundException e) {Log.error (e); } finally { if (inputstream! = null) { try { inputstream.close (); } catch (IOException e) { LOG.E Rror (e); }}}} public   void Automaticallycloseresource () { File File = new file ("./tmp.txt"); try ( FileInputStream InputStream = new FileInputStream (file);) { //Use the InputStream to read a file } catch (FileNotFoundException e) { log.error (e); } catch (IOE Xception e) { log.error (e); } }
2. Specify the specific exception

Use the most specific exceptions as much as possible to declare the method, which makes the code easier to understand.

123456    
public void doNotDoThis() throws Exception {    ...}public void doThis() throws NumberFormatException { ...}

As above, NumberFormatException literally can be seen as a numeric formatting error.

3. Documentation of exceptions

When declaring an exception on a method, a document description is also required. As in the previous point, it is all about providing the caller with as much information as possible to better avoid/handle exceptions.

Add the throws declaration to Javadoc and describe the scenario that throws the exception.

123456789       
/** * This method does something extremely useful ... * * @param input * @throws MyBusinessException if ... happens */public void doSomething(String input) throws MyBusinessException { ...}
4. Include descriptive information when throwing an exception

When you throw an exception, you need to describe the problem and related information as precisely as possible, so that you can read it more easily, either in the print to the log or in the monitoring tool, to better locate the specific error message, the severity of the error, and so on.

But this is not to say that you want to make a lengthy statement about the error message, because the exception class name can reflect the wrong reason, so you only need one or two words to describe it.

123)45   
try {    new Long("xyz");} catch (NumberFormatException e) {    log.error(e);}

NumberFormatException tells you that the exception is a format error, and that the extra information for the exception only needs to provide the error string. When the name of the exception is not obvious enough, you need to provide as much specific error information as possible.

5. First capture the most specific exception

Many IDES now intelligently hint at this best practice, and when you try to catch the most general exceptions first, you will be prompted for code that cannot be reached .

When there are multiple catch blocks, only the first matching catch block can be executed according to the capture order. Therefore, if you capture illegalargumentexception first, you cannot run to a capture of numberformatexception.

123456789       
public void catchMostSpecificExceptionFirst() {    try {        doSomething("A message");    } catch (NumberFormatException e) { log.error(e); } catch (IllegalArgumentException e) { log.error(e) }}
6. Do not capture Throwable

Throwable is the parent class for all exceptions and errors. You can capture it in a catch statement, but never do so.

If you catch throwable, you will not only catch all exception, but also catch the error. Error is a JVM error that indicates an unrecoverable failure. So unless you're absolutely sure you can handle or be asked to handle the error, don't capture Throwable.

1234567     
public void doNotCatchThrowable() {    try {        // do something    } catch (Throwable t) { // don‘t do this! }}
7. Do not ignore exceptions

Many times, developers are confident that they will not throw an exception, so they write a catch block, but do not do any processing or logging.

12345678      
public void doNotIgnoreExceptions() {    try {        // do something } catch (NumberFormatException e) { // this will never happen }}

But the reality is that there are often unpredictable anomalies or the inability to determine whether the code in the future will change (removing the code that prevents the exception from throwing), and because the exception is caught, so that it cannot get enough error information to locate the problem.

It is reasonable to record at least the information of the exception.

1234567     
public void logAnException() {    try {        // do something    } catch (NumberFormatException e) { log.error("This should never happen: " + e); }}
8. Do not record and throw exceptions

You can see that many code and even the class library have the logic to catch exceptions, log logs, and throw them again. As follows:

123456    
try {    new Long("xyz");} catch (NumberFormatException e) {    log.error(e); throw e;}

This processing logic is reasonable to look at. However, this often causes multiple logs to be output for the same exception. As follows:

1234567     
17:44:28,945 ERROR TestExceptionHandling:65 - java.lang.NumberFormatException: For input string: "xyz"Exception in thread "main" java.lang.NumberFormatException: For input string: "xyz"at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)at java.lang.Long.parseLong(Long.java:589)at java.lang.Long.(Long.java:965)at com.stackify.example.TestExceptionHandling.logAndThrowException(TestExceptionHandling.java:63)at com.stackify.example.TestExceptionHandling.main(TestExceptionHandling.java:58)

As shown above, there is no more useful information attached to the subsequent logs. If you want to provide more useful information, you can wrap the exception as a custom exception.

12345678      
public void wrapException(String input) throws MyBusinessException {    try {        // do something } catch (NumberFormatException e) { throw new MyBusinessException("A message that describes the error.", e); }}

Therefore, only when you want to handle the exception to capture, otherwise only need to declare in the method signature let the caller to handle.

9. Do not discard the original exception when packing the exception

Capturing standard exceptions and wrapping them as custom exceptions is a common practice. This allows you to add more specific exception information and be able to do the exception handling that is targeted.

It is important to note that the original exception must be set to cause when the wrapper is abnormal (exception has a construction method to pass in cause). Otherwise, the loss of the original exception information makes it difficult to parse the error.

1234567     
public void wrapException(String input) throws MyBusinessException {    try {        // do something    } catch (NumberFormatException e) { throw new MyBusinessException("A message that describes the error.", e); }}
Summarize

In conclusion, there are a lot of different things to consider when throwing or catching exceptions. Many of these points are designed to improve the readability of the code or the usability of the API.

Exceptions are not just an error-control mechanism, but also a communication medium, so discussing these best practices with your collaborators and developing specifications will allow everyone to understand the relevant generic concepts and be able to use them in the same way.

Ext.: http://www.rowkey.me/blog/2017/09/17/java-exception/

Java-exception Practice

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.