“This article has participated in the call for good writing activities, click to view: the back end, the big front end double track submission, 20,000 yuan prize pool waiting for you to challenge!”

Introduction to the

Java business development students often use try catch finally to catch exceptions, and there are three combinations used, try finally and try catch and try catch finally.

The sample

  • Try finally can be used as follows
Try {system.out.println (" business execution "); int i = 1 / 0; System.out.println(" Service execution completed "); }finally {system.out.println (" release resources "); }Copy the code

Some of you might be asking, “Try instead of catch,” is there anything like that? What does this mean??

  • try catch
Try {system.out.println (" business execution "); int i = 1 / 0; System.out.println(" Service execution completed "); }catch (Exception e){system.out.println (" catch Exception "); }Copy the code
  • Try catch finally is the way we usually do it

    Try {system.out.println (" business execution "); } catch (Exception e) {system.out.println (" catch Exception "); } finally {system.out.println (" release resources "); }Copy the code

    Since Java syntax supports writing this way, there is a use for it. I’ve posted a snippet of the famous thread pool code that executes the Work thread to show you how this usage is used extensively in the Java infrastructure, but we’re only aware of it.

final void runWorker(Worker w) { Thread wt = Thread.currentThread(); Runnable task = w.firstTask; w.firstTask = null; w.unlock(); // allow interrupts boolean completedAbruptly = true; try { while (task ! = null || (task = getTask()) ! = null) { w.lock(); // If pool is stopping, ensure thread is interrupted; // if not, ensure thread is not interrupted. This // requires a recheck in second case to deal with // shutdownNow race while clearing interrupt if ((runStateAtLeast(ctl.get(), STOP) || (Thread.interrupted() && runStateAtLeast(ctl.get(), STOP))) && ! wt.isInterrupted()) wt.interrupt(); try { beforeExecute(wt, task); try { task.run(); afterExecute(task, null); } catch (Throwable ex) { afterExecute(task, ex); throw ex; // there is no finnaly because there is no resource that must be released at the end} finally {// there is no catch exception, mainly because the following // completedAbruptly variable is used to determine whether the execution of the task throws an exception //1. //completedAbruptly = false; //completedAbruptly = false; //completedAbruptly = false; This line, because the outer try is // without a catch exception, //2. If the program can completedAbruptly=false, then there is no exception in the outer try part of the program. Indicates the normal execution of tasks. task = null; w.completedTasks++; w.unlock(); } } completedAbruptly = false; } finally { processWorkerExit(w, completedAbruptly); }}Copy the code

How to execute a return in try Catch Finally

public static int test() { int i = 0; Try {system.out.println (" business execution "); i = 1 / 0; System.out.println(" Service execution completed "); i++; return i; } catch (Exception e) {system.out.println (" catch Exception "); i++; return i; } finally {system.out.println (" release resources "); i++; return i; }}Copy the code

The result is as follows:

Here is the JVM bytecode decompiled from the above function javap, annotated for ease of understanding because the instructions are long

public static int test(); Descriptor: ()I flags: ACC_PUBLIC, ACC_STATIC Code: stack=2, locals=4, args_size=0 0: iconst_0 // Push constant 0 to operand stack 1: Istore_0 // store the top element of the operand stack at position 0 of the local variable table. getstatic #7 // Field java/lang/System.out:Ljava/io/PrintStream; // Get the static variable of PrintStream 5: LDC #25 invokevirtual #27 // Method java/io/PrintStream.println:(Ljava/lang/String;) V // Call the print function 10: iconst_1 // push constant 1 to the top of the operand stack 11: iconst_0 // push constant 0 to the top of the operand stack 12: idiv // divide two numbers from the operand stack 13: Istore_0 // Saves the result of the operation to position 0 in the table of local variables of the function. 14: getstatic #7 // Field java/lang/System.out:Ljava/io/PrintStream; 17: LDC #30 // String "business completed" constant pushed to the top of operand stack 19: LDC #30 invokevirtual #27 // Method java/io/PrintStream.println:(Ljava/lang/String;) V //pop the top element of the operand, call the print function, 22: iinc 0, 1 Istore_1 / / to save the operand stack element to the local variables of the no. 1 position: 27 getstatic # 7 / / Field Java/lang/System. Out: Ljava/IO/PrintStream; 30: LDC # 32 / / the String to release resources: invokevirtual # 27 / Java/Method/IO/PrintStream println (Ljava/lang/String;) 35: iInc 0, 1 // Execute local variable table index 0 position data add 1 38: iloAD_0 // execute local variable table index 0 position data push operand stack 39: ireturn // execute return 40: Astore_1 / / to save the operand stack elements to the index of local variables for the location of the 41:1 getstatic # 7 / / Field Java/lang/System. Out: Ljava/IO/PrintStream; 44: LDC # 36 / / String catch exceptions: 46 invokevirtual # 27 / Java/Method/IO/PrintStream println (Ljava/lang/String;) V 49: iinc 0, 1 // execute local variable table 0 position data add 1 52: iload_0 // execute local variable table 0 position data push operand stack 53: Istore_2 / / to save the operand stack elements to the location of the index of local variables to 2:54 getstatic # 7 / / Field Java/lang/System. Out: Ljava/IO/PrintStream; 57: LDC # 32 / / the String to release resources: 59 invokevirtual # 27 / Java/Method/IO/PrintStream println (Ljava/lang/String;) V print function 62: iinc 0, 1 // execute local variable table index 0 position data add 1 65: iloAD_0 // execute local variable table index 0 position data push operand stack 66: ireturn // execute return 67: Astore_3 / / to save the operand stack elements to the location of the index of local variables to 2, 68: getstatic # 7 / / Field Java/lang/System. Out: Ljava/IO/PrintStream; 71: LDC # 32 / / the String to release resources 73: invokevirtual # 27 / Java/Method/IO/PrintStream println (Ljava/lang/String;) V 76: iinc 0, 1 // execute local variable table index 0 add 1 79: iloAD_0 // execute local variable table index 0 add 1 80: ireturn // execute local variable table index 0 add 1 from to target type 2 27 40 Class java/lang/Exception 2 27 67 any 40 54 67 any LineNumberTable: line 27: 0 line 29: 2 line 30: 10 line 31: 14 line 32: 22 line 33: 25 line 39: 27 line 40: 35 line 41: 38 line 34: 40 line 35: 41 line 36: 49 line 37: 52 line 39: 54 line 40: 62 line 41: 65 line 39: 67 line 40: 76 line 41: 79 LocalVariableTable: Start Length Slot Name Signature 41 26 1 e Ljava/lang/Exception; 2 79 0 i I StackMapTable: number_of_entries = 2 frame_type = 255 /* full_frame */ offset_delta = 40 locals = [ int ] stack = [ class java/lang/Exception ] frame_type = 90 /* same_locals_1_stack_item */ stack = [ class java/lang/Throwable ]Copy the code

I++ is not executed in the try block because an exception was thrown. First catch i++ is executed, then finally i++ is executed, and then return is executed. The catch return is ignored from the bytecode. Because finally already has a return what would happen if the same program removed the return from finally

public static int test() { int i = 0; Try {system.out.println (" business execution "); i = 1 / 0; System.out.println(" Service execution completed "); i++; return i; } catch (Exception e) {system.out.println (" catch Exception "); i++; return i; } finally {system.out.println (" release resources "); i++; }}Copy the code

The result of the execution becomes 1. Why is that?

public static int test(); descriptor: ()I flags: ACC_PUBLIC, ACC_STATIC Code: stack=2, locals=4, args_size=0 0: iconst_0 1: istore_0 2: getstatic #7 // Field java/lang/System.out:Ljava/io/PrintStream; 5: LDC # 7:25 / / String the business execution invokevirtual # 27 / Java/Method/IO/PrintStream println (Ljava/lang/String;) V 10: iconst_1 11: iconst_0 12: idiv 13: istore_0 14: getstatic #7 // Field java/lang/System.out:Ljava/io/PrintStream; # 17: LDC 30 / / String business execution completed 19: invokevirtual # 27 / Java/Method/IO/PrintStream println (Ljava/lang/String;) V 22: iinc 0, 1 25: iload_0 26: istore_1 27: getstatic #7 // Field java/lang/System.out:Ljava/io/PrintStream; 30: LDC # 32 / / the String to release resources: invokevirtual # 27 / Java/Method/IO/PrintStream println (Ljava/lang/String;) V 35: iinc 0, 1 38: iload_1 39: ireturn 40: astore_1 41: getstatic #7 // Field java/lang/System.out:Ljava/io/PrintStream; 44: LDC # 36 / / String catch exceptions: 46 invokevirtual # 27 / Java/Method/IO/PrintStream println (Ljava/lang/String;) V 49: iinc 0, 1 52: iload_0 53: istore_2 54: getstatic #7 // Field java/lang/System.out:Ljava/io/PrintStream; 57: LDC # 32 / / the String to release resources: 59 invokevirtual # 27 / Java/Method/IO/PrintStream println (Ljava/lang/String;) V 62: iinc 0, 1 65: iload_2 66: ireturn 67: astore_3 68: getstatic #7 // Field java/lang/System.out:Ljava/io/PrintStream; 71: LDC # 32 / / the String to release resources 73: invokevirtual # 27 / Java/Method/IO/PrintStream println (Ljava/lang/String;) V 76: iinc 0, 1 79: aload_3 80: athrow Exception table: from to target type 2 27 40 Class java/lang/Exception 2 27 67 any 40 54 67 anyCopy the code

The catch is loaded onto the operand stack by adding one to the index 1 in the local variable table. Last store to the position where the index of the local variable table is 2.

When executing finally, the index of the index variable 0 is 1 + 1, which becomes 2. When executing finally, the ireturn is the first operation, which returns the value from iload_2, the local variable 2. Does not change the return value.

conclusion

This article mainly summarizes the process of the implementation principle of the basic Try Catch Finally in Java. I hope I can understand the truth when I write code and read other people’s code.