Try-catch in-depth understanding
Let's look at an example (example 1) to explain the process of try, catch, finally in Java
1234567891011121314151617181920212223 |
public
class
TryCatchFinally {
@SuppressWarnings
(
"finally"
)
public
static
final String test() {
String t =
""
;
try
{
t =
"try"
;
return t;
}
catch
(Exception e) {
// result = "catch";
t =
"catch"
;
return t;
}
finally
{
t =
"finally"
;
}
}
public static
void
main(String[] args) {
System.out.print(TryCatchFinally.test());
}
}
|
First the program executes the TRY statement block, assigns the variable t to try, because no exception is found, then executes the finally statement block, assigns the variable t to finally, and then return T, the value of T is finally, the value of the last T is Finally, The result of the program should show finally, but the actual result is try. Why this is so, we might as well first look at this code compiled by the class corresponding byte code, see how the virtual machine inside is executed.
We use Javap-verbose trycatchfinally to display the target file (. class file) bytecode information
System operating environment: Mac OS Lion system 64bit
JDK Information: Java (tm) SE Runtime Environment (build 1.6.0_29-b11-402-11m3527) Java HotSpot (tm) 64-bit Server VM (Build 20.4-b02-4 Mixed mode)
Compiled byte-code part of the information, we only see the test method, the other first ignored
public static final java.lang.String test (); Code:stack=1, locals=4, args_size=0 0:LDC #16; String 2:astore_0 3:LDC #18; String try 5:astore_0 6:aload_0 7:astore_3 8:LDC #20; String finally 10:astore_0 11:aload_3 12:areturn 13:astore_1 14:ldc #22; String catch 16:astore_0 17:aload_0 18:astore_3 19:LDC #20; String finally 21:astore_0 22:aload_3 23:areturn 24:astore_2 25:ldc #20; String finally 27:astore_0 28:aload_2 29:athrow Exception table:from to target type 3 8 Class java/lang/exception 3 8 any linenumbertable:line 5:0 line 8 : 3 line 9:6 line 15:8 line 9:11 line 10:13 line 12:14 line 13:17 line 15:19 line 13:22 line 14: Line 15:25 line 16:28 localvariabletable:start Length Slot Name Signature 3 0 T Ljava/lang/string; 1 e ljava/lang/exception; Stackmaptable:number_of_entries = 2 Frame_type = 255/* Full_frame */Offset_delta = locals = [Class java/l Ang/string] Stack = [Class java/lang/exception] Frame_type = */same_locals_1_stack_item */stack = [Clas S java/lang/throwable]
First look at the localvariabletable information, which defines two variables, one is the T string type, and the other is the E Exception type
Next look at the code section
line [0-2], assign a value to the No. 0 variable "", that is, string t= "";
line [3-6], which is the execution of a TRY statement block assignment statement, that is, T = "Try";
Line 7th, focus on line 7th, the value "try" corresponding to the third variable, but there is no definition of the third variable, this is rather strange
line [8-10], the No. 0 variable assignment operation, that is t= "finally"
line [11-12], return the value corresponding to the third variable
Through bytecode, we find that in the return block of a try statement, the reference variable returned by return (T is a reference type) is not a reference variable defined in the Try statement, but rather the system redefined a local reference T ', which refers to the value of reference T, which is the try, Even if the reference T is pointed to the value finally in the finally statement because the return reference of return is not T, the corresponding value of the reference T is irrelevant to the return value in the Try statement.
Here is an example: (Example 2)
1 public class Trycatchfinally {2 3 @SuppressWarnings ("finally") 4 public static final String test () {5 String t = ""; 6 7 try {8 t = "Try"; 9 return t;10 } catch (Exception e) {One //result = "catch"; t = "CA Tch "; return t;14 } finally { t =" finally "; return t;17 }18 }19 static void Main (string[] args) { System.out.print (trycatchfinally.test ()); }23 24}
The first piece of code is changed slightly, but the expression of return T is added to the finally statement block.
According to the first paragraph of the code, the first try{} statement, and then before the return of the current value of T try to save to a variable t ', and then execute a finally statement block, modified the value of the variable T, in the return variable T.
There are two return statements, but whether the program returns a try or a finally. Next, we'll look at the bytecode information.
public static final java.lang.String test (); Code:stack=1, locals=2, args_size=0 0:LDC #16; String 2:astore_0 3:LDC #18; String try 5:astore_0 6:goto 9:astore_1 10:LDC #20; String catch 12:astore_0 13:goto 16:pop 17:LDC #22; String finally 19:astore_0 20:aload_0 21:areturn Exception table:from to target type 3 9 9 Class java/lang/exception 3 linenumbertable:line 5:0 line 8:3 line 9:6 Line 10:9 line 12:10 line 13:13 line 14:16 line 15:17 line 16:20 localvariabletable:start Length Slot N Ame Signature 3 0 T ljava/lang/string; 6 1 E ljava/lang/exception; Stackmaptable:number_of_entries = 3 Frame_type = 255/* Full_frame */Offset_delta = 9 locals = [Class java/la Ng/string] Stack = [Class java/lang/exception] Frame_type = */* same_locals_1_stack_item * * stack = [Class java/lang/throwable] Frame_type = 0/* Same */
This code translates the byte code completely different from the first one, or continues to see Code properties
[0-2] Line, [3-5] line the first paragraph of the code logic is similar to initialize T, try to assign a value of the try
Line 6th, where the face jumps to line 17th, [17-19] is to execute finally inside the assignment statement, the variable t is assigned to finally, and then return t corresponding value
We found the return statement in the TRY statement to be ignored. It is possible that the JVM thinks that there are two return statements in a method that do not make much sense, so the return statement in the try is ignored and the return statement in the finally is the direct function, so this time it returns finally.
The next step is to look at some of the more complicated examples: (example 3)
public class Trycatchfinally { @SuppressWarnings ("finally") public static final String test () { string t = "" ; try { T = "Try"; Integer.parseint (null); return t; } catch (Exception e) { t = "catch"; return t; } finally { T = "finally"; System.out.println (t); return t; } } public static void Main (string[] args) { System.out.print (trycatchfinally.test ());} }
This inside the try statement will throw Java.lang.NumberFormatException, so the program will first execute the logic in the catch statement, T is assigned to catch, and before the return, will be saved to a temporary variable inside T ', Execute finally logic, T is assigned to finally, but the return value and T ', so the value of the variable T and the return value is no longer related, the return is a catch
Example 4:
public class Trycatchfinally { @SuppressWarnings ("finally") public static final String test () { string t = "" ; try { T = "Try"; Integer.parseint (null); return t; } catch (Exception e) { t = "catch"; return t; } finally { T = "finally"; return t; } } public static void Main (string[] args) { System.out.print (trycatchfinally.test ());} }
This is somewhat similar to Example 2, because a try statement throws an exception, the program goes to a catch statement block, the catch statement executes a finally after executing the return statement, and the finally statement has a return, then executes the finally statement value directly. Return to finally
Example 5:
public class Trycatchfinally { @SuppressWarnings ("finally") public static final String test () { string t = "" ; try { T = "Try"; Integer.parseint (null); return t; } catch (Exception e) { t = "catch"; Integer.parseint (null); return t; } finally { T = "finally"; return t; } } public static void Main (string[] args) { System.out.print (trycatchfinally.test ());} }
This example adds a integer.parser (NULL) statement to the catch statement block, forcing an exception to be thrown. Then there is no return statement inside the finally statement block. To continue the analysis, because the try statement throws an exception, the program enters the catch statement block, the catch statement block throws an exception, indicating that the catch statement to exit, then execute the FINALLY statement block, the T is assigned value. Then an exception is thrown inside the catch statement block. The result is a throw java.lang.NumberFormatException exception
Example 6:
public class Trycatchfinally { @SuppressWarnings ("finally") public static final String test () { string t = "" ; try { T = "Try"; Integer.parseint (null); return t; } catch (Exception e) { t = "catch"; Integer.parseint (null); return t; } finally { T = "finally"; return t; } } public static void Main (string[] args) { System.out.print (trycatchfinally.test ());} }
The only difference between this example and the example above is that the finally statement in this example has a return statement block. The logic that runs in the try catch is the same as the example above, and when an exception is thrown inside a catch statement block, enter the finally statement fast, and then return T. The program ignores the exception information thrown in the catch statement block and returns the value of T corresponding to the finally. method does not throw an exception
Example 7:
public class Trycatchfinally { @SuppressWarnings ("finally") public static final String test () { string t = "" ; try { T = "Try"; Integer.parseint (null); return t; } catch (NullPointerException e) { t = "catch"; return t; } finally { T = "finally"; } } public static void Main (string[] args) { System.out.print (trycatchfinally.test ());} }
In this example, the catch statement inside catch is the NPE exception, Instead of the java.lang.NumberFormatException exception, it does not enter the Catch statement block, directly into the finally statement block, finally after the S assignment, by the try statement throws Java.lang.NumberFormatException Often.
Example 8
public class Trycatchfinally { @SuppressWarnings ("finally") public static final String test () { string t = "" ; try { T = "Try"; Integer.parseint (null); return t; } catch (NullPointerException e) { t = "catch"; return t; } finally { T = "finally"; return t; } } public static void Main (string[] args) { System.out.print (trycatchfinally.test ());} }
The same logic as the try catch in the example above, the try statement execution finishes executing the FINALLY statement, finally assigns the value s and returns S, and the final program result returns finally
Example 9:
public class Trycatchfinally { @SuppressWarnings ("finally") public static final String test () { string t = "" ; try { T = "Try"; return t; } catch (Exception e) { t = "catch"; return t; } finally { T = "finally"; String.valueof (null); return t; } } public static void Main (string[] args) { System.out.print (trycatchfinally.test ());} }
In this example, string.valueof (null) is added to the finally statement to force the NPE exception to be thrown. First the program executes a try statement, returns execution, executes the finally statement block, the finally statement throws a NPE exception, and the entire result returns a NPE exception.
A summary of all the above examples
1 in a try, catch, finally statement, if the try statement has a return statement, then the value of the variable in the current try is returned, and any subsequent modifications to the variable do not affect the return value in the try
2 If there is a return statement in the finally block, returns the return statement in the try or catch is ignored.
3 If an exception is thrown in a finally block, an exception is thrown in the entire try, catch, finally block
So the use of try, catch, and finally statement blocks should be noted
1 Use the return statement as much as possible in a try or catch. It is not feasible to modify the return value of a try or catch by reaching the finally block.
Avoid using the return statement in the 2 finally block, because if the return statement is used in the finally block, the exception information in the try, catch block is displayed, shielding the error from occurring
3 Finally block avoid throwing an exception again, otherwise the entire method containing the try statement block throws an exception, and the exception in the try, catch block is digested
This article transferred from: http://www.cnblogs.com/aigongsi/archive/2012/04/19/2457735.html
Try-catch in-depth understanding