zoukankan      html  css  js  c++  java
  • [转]java的异常处理最佳实践

    本文转载自 Karibasappa G C (KB), the Founder of javainsimpleway.com, 原文链接 http://javainsimpleway.com/exception-handling-best-practices/

    Exception handling is one of the non-functional requirements for any application development.

    We should handle erroneous situations gracefully using exception handling.

    Example : Invalid input, File not found in system while reading , number format is not correct etc.

    Java provides exception handling to handle these scenarios using try-catch blocks.

    There are some set of rules or best practices which we need to follow in exception handling.

    Let’s discuss some best practices below

    Practice 1

    Execute Clean up Resources in a Finally Block or Use a Try-With-Resource Statement

    We generally use resource statements like opening a file, or connecting to database etc in the try block and we close it at the end of try block

    Example :

    1. package com.kb.Exception;
    2.  
    3. import java.io.BufferedReader;
    4. import java.io.FileReader;
    5. import java.io.IOException;
    6.  
    7. public class ExceptionHandlingCloseResource {
    8.  
    9.     public static void main(String[] args{
    10.         FileReader fileReader null;
    11.         BufferedReader bufferedReader null;
    12.         try {
    13.             System.out.println("Code to read the data from File");
    14.             fileReader new FileReader("sample.txt");
    15.  
    16.             bufferedReader new BufferedReader(fileReader);
    17.  
    18.             String line;
    19.             while ((line = bufferedReader.readLine()!= null{
    20.                 System.out.println(line);
    21.             }
    22.  
    23.             if (bufferedReader != null{
    24.                 bufferedReader.close();
    25.             }
    26.             if (fileReader != null{
    27.                 fileReader.close();
    28.             }
    29.  
    30.         catch (IOException e{
    31.             System.out.println("Inside  catch block");
    32.         }
    33.  
    34.     }
    35.  
    36. }


    What happens in the above code if there is any exception is thrown in try block ?

    Example : While reading file, it may throw FileNotFoundException and thus further lines in try block will not be executed and control goes to catch block.

    Because of this, we may end up with not closing the resource which leads to resource leakage.

    Its always recommended to write resource closing statements inside finally block as it executes all the time no matter whether exception is thrown or not

    1. package com.kb.Exception;
    2.  
    3. import java.io.BufferedReader;
    4. import java.io.FileReader;
    5. import java.io.IOException;
    6.  
    7. public class ExceptionHandlingCloseResource {
    8.  
    9.     public static void main(String[] args{
    10.         FileReader fileReader null;
    11.         BufferedReader bufferedReader null;
    12.         try {
    13.             System.out.println("Code to read the data from File");
    14.             fileReader new FileReader("sample.txt");
    15.  
    16.             bufferedReader new BufferedReader(fileReader);
    17.  
    18.             String line;
    19.             while ((line = bufferedReader.readLine()!= null{
    20.                 System.out.println(line);
    21.             }
    22.  
    23.         catch (IOException e{
    24.             System.out.println("Inside  catch block");
    25.         }
    26.  
    27.         finally {
    28.             if (bufferedReader != null{
    29.                 try {
    30.                     bufferedReader.close();
    31.                 catch (IOException e{
    32.                     System.out.println("Log exception while closing bufferedReader");
    33.                 }
    34.             }
    35.             if (fileReader != null{
    36.                 try {
    37.                     fileReader.close();
    38.                 catch (IOException e{
    39.                     System.out.println("Log exception while closing fileReader");
    40.                 }
    41.             }
    42.         }
    43.  
    44.     }
    45.  
    46. }
    Practice 2

    Never swallow the exception in catch block

    1. catch (IOException e{
    2.    return null;
    3. }


    Sometime if our method needs some return value then we handle exception inside catch block and return NULL.

    This is dangerous as returning NULL may cause NullPointerException at the caller side and in addition to that we are losing the actual cause of exception

    Its better to handle it properly or rethrow the meaningful exception back to caller as below

    1. catch (IOException e{
    2. throw new FileNotFoundException(“File not exist”);
    3. }
    Practice 3

    Declare specific exceptions rather than generic exception using throws

    1. public void readFile(throws Exception {
    2. }


    In the above case, we are wrapping up all the exception into one Exception which does not give much information to caller.

    If there are multiple exceptions needs to be thrown then declare each exception separately or create one custom exception and wrap those exceptions in our custom exception and provide meaningful message to caller.

    We can do so as below

    1. public void readFile(throws IOException,SQLException {
    2. }
    Practice 4

    Catch most specific exceptions first and then generic exception

    This is anyway will not be allowed by java compiler only if we don’t follow this.

    We need to write catch blocks for more specific exceptions first as they can be handled first and then generic exception catch block can be written later

    1. public void catchSpecificExceptionFirst({
    2.     try {
    3.         readFile("sample.txt");
    4.     catch (FileNotFoundException e{
    5.         System.out.println("Log FileNotFoundException while reading file");
    6.     catch (IOException e{
    7.         System.out.println("Log IOException while reading file");
    8.     }
    9. }


    In this case, FileNotFoundException is a subclass of IOException and hence that has to be handled first.

    Practice 5

    Don’t catch Throwable

    We know that Throwable is the superclass of all exceptions and errors

    We can use Throwable in catch block but we should never do it

    Although errors are subclasses of the Throwable, Errors are irreversible conditions that cannot be handled by JVM itself and hence it is not advised to write catch block with Throwable

    Practice 6

    Correctly wrap the exception details and send it to caller

    Its important to wrap the exception details so that exception trace will not be lost

    Example : We should not do it like below

    1. catch (FileNotFoundException e{
    2.    throw new CustomException("Custom message: " + e.getMessage());
    3. }

    Instead we can do it as below

    1. catch (FileNotFoundException e{
    2.    throw new CustomException("Custom message: " ,e);
    3. }
    Practice 7

    Don’t log and throw exception instead do one of these 2, but never do both

    1. catch (FileNotFoundException e{
    2.    LOGGER.error("Custom message", e);
    3.    throw e;
    4. }


    Logging and throwing the same exception in the same place will result in multiple log messages in log files and makes confusion while analysing the logs

    Practice 8

    Throw early catch late

    This is the most famous principle about Exception handling.

    We should throw an exception as soon as we can and we should catch it as late as we can

    It means we should throw an exception in low level methods where we execute our business logic and make sure exception is thrown to several layers until we reach specific layer to handle it

    Example :
    Throw exception in Service layer and handle it in controller in Spring MVC application

    Practice 9

    Always use single LOG statement to log exception

    Example :

    1. LOGGER.error(“exception occurred “);
    2. LOGGER.error(e.getMessage());


    If we use multiple LOG statements , It makes multiple calls to Logger and also while writing log, this information may not come together as writing to log happens with multi-threading and all threads dump information to same log file which results these lines to spread in different place in log file.

    Instead, we can write it using single LOG statement as below

    1. LOGGER.error(“exception occurred “+e.getMessage());
    Practice 10

    Avoid empty catch blocks

    This is one of the worst coding if you are keeping empty catch block as it hides the exception thrown and there is no handling of that exception, Even if we don’t want to handle it , its better to at least log the exception details in catch block.

    Practice 11

    Create custom exception only if its necessary

    Java has provided lot of exception which can be used in various scenarios

    In case, we need to provide additional information then only we should go for custom exception

    Practice 12

    Document the exceptions using Javadoc

    Whenever method throws any exception, its better to document its details using @throw annotation of Javadoc

    Clear documentation of Exception thrown by any method provides complete idea of exception to anyone who is using it.

    Conclusion
    We know that exception handling is very important in software application development
    We should also consider the best practices in handling the exception which not only increases the readability of program but also provides robust way of handling the exceptions.
  • 相关阅读:
    c++常用库
    boost
    android
    UITableView 多选
    c++ 比较两个集合
    事件加不上的另一种原因
    ios多线程
    ubuntu android
    jna StdCallCallback 回调问题查证
    java
  • 原文地址:https://www.cnblogs.com/harrychinese/p/java_exception_handling_best_practice.html
Copyright © 2011-2022 走看看