java中finally子句的分析
来源:互联网 发布:最奇葩的淘宝差评有图 编辑:程序博客网 时间:2024/06/11 19:24
java中finally子句是怎么运行的?
看下面的程序:
public class JVMTest {
public static void main(String[] args){
System.out.println("aa:" + aa());
}
public static int aa(){
int a = 1;
int b = 10;
try{
System.out.println("abc");
return a;
}finally{
a = 2;
System.out.println("a: "+ a);
}
}
}
运行结果为:
abc
a: 2
aa:1
由此可知:在try语句中,在执行return语句时,要返回的结果已经准备好了,就在此时,程序转到finally执行了。
在转去之前,try中先把要返回的结果存放到不同于a的局部变量中去,执行完finally之后,在从中取出返回结果,
因此,即使finally中对变量a进行了改变,但是不会影响返回结果。
但是,如果在finally子句中最后添加上return a会怎样呢?
执行结果如下:
Compiling 1 source file to E:/sun/InsideJVM/build/classes
E:/sun/InsideJVM/src/JVMTest.java:37: warning: finally clause cannot complete normally
}
1 warning
compile-single:
run-single:
abc
a: 2
aa:2
具体的分析可以借助于javap,(为便于分析,注释掉了输出语句):
例如:javap -v JVMTest (没加return a;前)
结果为:
E:/sun/InsideJVM/build/classes>javap -v JVMTest
Compiled from "JVMTest.java"
public class JVMTest extends java.lang.Object
SourceFile: "JVMTest.java"
minor version: 0
major version: 0
Constant pool:
const #1 = Method #12.#31; // java/lang/Object."<init>":()V
const #2 = Field #32.#33; // java/lang/System.out:Ljava/io/PrintS
tream;
const #3 = class #34; // StringBuffer
const #4 = Method #3.#31; // java/lang/StringBuffer."<init>":()V
const #5 = String #35; // aa:
const #6 = Method #3.#36; // java/lang/StringBuffer.append:(Ljava/lang/St
ring;)Ljava/lang/StringBuffer;
const #7 = Method #11.#37; // JVMTest.aa:()I
const #8 = Method #3.#38; // java/lang/StringBuffer.append:(I)Ljava/lang/
StringBuffer;
const #9 = Method #3.#39; // java/lang/StringBuffer.toString:()Ljava/lang
/String;
const #10 = Method #40.#41; // java/io/PrintStream.println:(Ljava/l
ang/String;)V
const #11 = class #42; // JVMTest
const #12 = class #43; // Object
const #13 = Asciz <init>;
const #14 = Asciz ()V;
const #15 = Asciz Code;
const #16 = Asciz LineNumberTable;
const #17 = Asciz LocalVariableTable;
const #18 = Asciz this;
const #19 = Asciz LJVMTest;;
const #20 = Asciz main;
const #21 = Asciz ([Ljava/lang/String;)V;
const #22 = Asciz args;
const #23 = Asciz [Ljava/lang/String;;
const #24 = Asciz aa;
const #25 = Asciz ()I;
const #26 = Asciz a;
const #27 = Asciz I;
const #28 = Asciz b;
const #29 = Asciz SourceFile;
const #30 = Asciz JVMTest.java;
const #31 = NameAndType #13:#14;// "<init>":()V
const #32 = class #44; // System
const #33 = NameAndType #45:#46;// out:Ljava/io/PrintStream;
const #34 = Asciz java/lang/StringBuffer;
const #35 = Asciz aa:;
const #36 = NameAndType #47:#48;// append:(Ljava/lang/String;)Ljava/lang/String
Buffer;
const #37 = NameAndType #24:#25;// aa:()I
const #38 = NameAndType #47:#49;// append:(I)Ljava/lang/StringBuffer;
const #39 = NameAndType #50:#51;// toString:()Ljava/lang/String;
const #40 = class #52; // PrintStream
const #41 = NameAndType #53:#54;// println:(Ljava/lang/String;)V
const #42 = Asciz JVMTest;
const #43 = Asciz java/lang/Object;
const #44 = Asciz java/lang/System;
const #45 = Asciz out;
const #46 = Asciz Ljava/io/PrintStream;;
const #47 = Asciz append;
const #48 = Asciz (Ljava/lang/String;)Ljava/lang/StringBuffer;;
const #49 = Asciz (I)Ljava/lang/StringBuffer;;
const #50 = Asciz toString;
const #51 = Asciz ()Ljava/lang/String;;
const #52 = Asciz java/io/PrintStream;
const #53 = Asciz println;
const #54 = Asciz (Ljava/lang/String;)V;
{
public JVMTest();
Code:
Stack=1, Locals=1, Args_size=1
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: return
LineNumberTable:
line 21: 0
line 23: 4
LocalVariableTable:
Start Length Slot Name Signature
0 5 0 this LJVMTest;
public static void main(java.lang.String[]);
Code:
Stack=3, Locals=1, Args_size=1
0: getstatic #2; //Field java/lang/System.out:Ljava/io/PrintStream;
3: new #3; //class StringBuffer
6: dup
7: invokespecial #4; //Method java/lang/StringBuffer."<init>":()V
10: ldc #5; //String aa:
12: invokevirtual #6; //Method java/lang/StringBuffer.append:(Ljava/lang/S
tring;)Ljava/lang/StringBuffer;
15: invokestatic #7; //Method aa:()I
18: invokevirtual #8; //Method java/lang/StringBuffer.append:(I)Ljava/lang
/StringBuffer;
21: invokevirtual #9; //Method java/lang/StringBuffer.toString:()Ljava/lan
g/String;
24: invokevirtual #10; //Method java/io/PrintStream.println:(Ljava/lang/St
ring;)V
27: return
LineNumberTable:
line 25: 0
line 26: 27
LocalVariableTable:
Start Length Slot Name Signature
0 28 0 args [Ljava/lang/String;
public static int aa();
Code:
Stack=1, Locals=4, Args_size=0
0: iconst_1
1: istore_0
2: bipush 10
4: istore_1
5: iload_0
6: istore_2
7: iconst_2
8: istore_0
9: iload_2
10: ireturn
11: astore_3
12: iconst_2
13: istore_0
14: aload_3
15: athrow
Exception table:
from to target type
5 7 11 any
11 12 11 any
LineNumberTable:
line 28: 0
line 29: 2
line 32: 5
line 34: 7
LocalVariableTable:
Start Length Slot Name Signature
2 14 0 a I
5 11 1 b I
}
E:/sun/InsideJVM/build/classes>
从第5,6可知,执行return前,已经把结果准备好了,并存到了第二个局部变量(不是第0个:a)中。
加入return a;之后的情形可类似分析,此处略之。
- java中finally子句的分析
- java中finally子句的分析
- finally子句和try子句中return的先后关系
- Finally子句的用法
- finally子句和try子句中return的先后关系 -- http://blog.csdn.net/zcjl/
- 关于 Java 中 try、finally 语句块的分析
- finally子句在虚拟机的实现
- Java中 Finally的解析
- java异常—— finally 子句+带资源的 try语句
- java中return与finally的执行顺序分析(根据字节码分析)
- java中return与finally的执行顺序分析(根据字节码分析)
- Java的finally块执行分析
- finally 子句 try finally 语句
- 关于Java中try finally return语句的执行顺序分析
- 关于Java中try finally return语句的执行顺序分析
- Java中finally的执行问题
- Java中finally关键字的使用--转载
- Java中finally关键字的使用
- VirtualBox 学习(一)
- 不错的手机正则表达式,解释的也还不错.
- iconv使用
- javap
- /etc/passwd和etc/group中每条记录个字段的含义
- java中finally子句的分析
- 七嘴八舌
- OpenGL基础知识(三)
- Jsonp 方式跨域获取 json 数据原理
- TopCoder兼职赚钱入门
- 近乎完美的简单 JS 跨域解决方式 --window.name
- C++中竟然可以用 ... 这样省略形参
- 数据集
- TTPhotoViewController 在不同interfaceOrientation下的显示问题