The introduction

The inspiration for this article comes from

Exception, this noun should be very familiar to the development of students, is in our program error or business logic is not when, give the program a safe exit channel

How to handle exceptions gracefully is an art, this article will give you the correct posture to handle exceptions (by default, you have mastered the basic knowledge of exceptions)

Elegant exception handling

Online code disallows printStackTrace()

PrintStackTrace () only prints error stack information on the console, and it is only suitable for code debugging.

If you really need to log exceptions, use logging

Runtimeexceptions defined in the Java class library that can be circumvented by pre-checking should not be handled by catch

For example: NullPointerException, IndexOutOfBoundsException and so on.

Note: Exceptions that do not pass the pre-check. For example, when parsing a number as a string, there may be a number format error and you have to catch NumberFormatException.

/ / is
if(obj ! =null) {... }/ /
try { obj.method(); } catch(NullPointerException e) {... }Copy the code

Do not use the exception capture to do process control, condition control

The original intention of exception design is to solve various unexpected situations in program running, rather than do condition control like Iflese. Business logic is done in catch, which generally handles exception throwing and log recording, and the efficiency of exception processing is much lower than that of condition judgment

When catching, distinguish between stable code and unstable code. Stable code is code that will not fail no matter what. For the catch of unstable code, distinguish the exception type as much as possible, and then do the corresponding exception handling

It is irresponsible to try and catch large chunks of code so that the program does not respond correctly to different exceptions and is not good for locating the problem.

For example, if we have a user withdrawal logic, we need to throw an exception to tell the program that the balance is insufficient and the poor guy is not allowed to withdraw, that this is a bad guy and he entered the wrong password, etc., rather than prompt the withdrawal failure all the time

An exception is caught to handle it, don’t throw it away and do nothing with it. If you don’t want to handle it, throw the exception to its caller. The outermost business consumer must handle the exception and translate it into something the user can understand

/ /
catch (NoSuchMethodException e) {
   return null;
}

/ / is
catch (NoSuchMethodException e) {
   throw new BizException("Error code"."Wrong cause")}Copy the code

In transaction scenarios, if you need to roll back after a catch throws an exception, it is important to manually roll back the transaction

/ / is
public void test(a) {
      TransactionDefinition tra = new DefaultTransactionDefinition();
      TransactionStatus status = transactionManager.getTransaction(tra);

       try {
         // Transaction operations
         // Transaction commit
         transactionManager.commit(status);
      } catch (DataAccessException e) {
         // Transaction commit
         transactionManager.rollback(status);
         throwe; }}Copy the code

Finally blocks must close resource objects, stream objects, and try-catch exceptions

// Usual practice
catch (Exception e) {
		e.printStackTrace(); // The first exception is handled
	}
	finally {
        try {
            if(c ! =null) { c.close(); }}catch (IOException e) {
            e.printStackTrace(); // The second exception is handled}}// Note: if JDK7 or later, try-with-resources can be used.
public class Main {
    public static void startTest(a) {
        try (MyAutoCloseA a = new MyAutoCloseA();
             MyAutoCloseB b = new MyAutoCloseB()) {
            a.test();
            b.test();
        } catch (Exception e) {
            System.out.println("Main: exception");
            System.out.println(e.getMessage());
            Throwable[] suppressed = e.getSuppressed();
            for (int i = 0; i < suppressed.length; i++) System.out.println(suppressed[i].getMessage()); }}public static void main(String[] args) throws Exception { startTest(); }}Copy the code

Do not use a return ina finally block

After the successful execution of the return statement in the try block, it does not return immediately. Instead, it continues to execute the statement in the finally block. If this point is stored in the return statement, it will return directly from here and discard the return point in the try block ruthlessly.

    / / the case:
    private int x = 0;
    public int checkReturn(a) {
        try {
            // x is equal to 1, not return here
            return ++x;
        } finally {
            // 返回的结果是 2
            return++x; }}Copy the code

Also, do not throw an exception ina finally block

The catch exception and the throw exception must be an exact match, or the catch exception is the parent of the throw exception

If the expected throw is hydrangea and the shot is actually put, there will be an unexpected situation.

When an RPC, a two-party package, or the related methods of a dynamically generated class are called, catching exceptions must be intercepted using the Throwable class

The method is called through the reflection mechanism, and if the method is not found, a NoSuchMethodException is thrown. In what cases will NoSuchMethodError be raised? In the event of a class conflict, the mediation mechanism may lead to the introduction of an unexpected version that causes the method signatures of the class to be mismatched, or to change the corresponding method signatures when a bytecode modification framework (such as ASM) dynamically creates or modifs the class. In these cases, NoSuchMethodError is raised at runtime, even if the code is correct at compile time

If you do not intend to handle exceptions, use a Finally block instead of a catch block

try {
  someMethod(); 
} 
finally
{
  cleanUp();    
}
Copy the code

If an exception occurs ina method and you don’t want to handle it, you can handle it directly in the finally, without the need for a catch


Reference:

Alibaba: Java Development Manual

I’m Skow

Give me a like and I’ll see you next time