查了很多资料,都说之前,但是public class test{
int i=0;
public int f(){
try{
return i;
}finally{
i++;
}
}
public static void main(String args[]){
test t = new test();
System.out.println(t.i+","+t.f()+","+t.i);
}
}
========================================
C:\java>java test
0,0,1
=======================================
C:\java>javap -c test
Compiled from "test.java"
public class test extends java.lang.Object{
int i; public test();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: aload_0
5: iconst_0
6: putfield #2; //Field i:I
9: return public int f();
Code:
0: aload_0
1: getfield #2; //Field i:I
4: istore_1
5: aload_0
6: dup
7: getfield #2; //Field i:I
10: iconst_1
11: iadd
12: putfield #2; //Field i:I
15: iload_1
16: ireturn
17: astore_2
18: aload_0
19: dup
20: getfield #2; //Field i:I
23: iconst_1
24: iadd
25: putfield #2; //Field i:I
28: aload_2
29: athrow
Exception table:
from to target type
0 5 17 any
17 18 17 any public static void main(java.lang.String[]);
Code:
0: new #3; //class test
3: dup
4: invokespecial #4; //Method "<init>":()V
7: astore_1
8: getstatic #5; //Field java/lang/System.out:Ljava/io/PrintStream;
11: new #6; //class java/lang/StringBuilder
14: dup
15: invokespecial #7; //Method java/lang/StringBuilder."<init>":()V
18: aload_1
19: getfield #2; //Field i:I
22: invokevirtual #8; //Method java/lang/StringBuilder.append:(I)Ljava/lan
g/StringBuilder;
25: ldc #9; //String ,
27: invokevirtual #10; //Method java/lang/StringBuilder.append:(Ljava/lang
/String;)Ljava/lang/StringBuilder;
30: aload_1
31: invokevirtual #11; //Method f:()I
34: invokevirtual #8; //Method java/lang/StringBuilder.append:(I)Ljava/lan
g/StringBuilder;
37: ldc #9; //String ,
39: invokevirtual #10; //Method java/lang/StringBuilder.append:(Ljava/lang
/String;)Ljava/lang/StringBuilder;
42: aload_1
43: getfield #2; //Field i:I
46: invokevirtual #8; //Method java/lang/StringBuilder.append:(I)Ljava/lan
g/StringBuilder;
49: invokevirtual #12; //Method java/lang/StringBuilder.toString:()Ljava/l
ang/String;
52: invokevirtual #13; //Method java/io/PrintStream.println:(Ljava/lang/St
ring;)V
55: return }
...
public int f(){
try{
return 1;
}finally{
return 2;
}
}
...
会return 2,原因是return之前执行finally
但是
...
public int f();
Code:
0: iconst_1
1: istore_1
2: iconst_2
3: ireturn
4: astore_2
5: iconst_2
6: ireturn
Exception table:
from to target type
0 2 4 any
4 5 4 any
...
我怎么看也觉得,是return之后,执行finally时再度return,覆盖了原先的返回值 麻烦哪位高手解释一下,谢谢
int i=0;
public int f(){
try{
return i;
}finally{
i++;
}
}
public static void main(String args[]){
test t = new test();
System.out.println(t.i+","+t.f()+","+t.i);
}
}
========================================
C:\java>java test
0,0,1
=======================================
C:\java>javap -c test
Compiled from "test.java"
public class test extends java.lang.Object{
int i; public test();
Code:
0: aload_0
1: invokespecial #1; //Method java/lang/Object."<init>":()V
4: aload_0
5: iconst_0
6: putfield #2; //Field i:I
9: return public int f();
Code:
0: aload_0
1: getfield #2; //Field i:I
4: istore_1
5: aload_0
6: dup
7: getfield #2; //Field i:I
10: iconst_1
11: iadd
12: putfield #2; //Field i:I
15: iload_1
16: ireturn
17: astore_2
18: aload_0
19: dup
20: getfield #2; //Field i:I
23: iconst_1
24: iadd
25: putfield #2; //Field i:I
28: aload_2
29: athrow
Exception table:
from to target type
0 5 17 any
17 18 17 any public static void main(java.lang.String[]);
Code:
0: new #3; //class test
3: dup
4: invokespecial #4; //Method "<init>":()V
7: astore_1
8: getstatic #5; //Field java/lang/System.out:Ljava/io/PrintStream;
11: new #6; //class java/lang/StringBuilder
14: dup
15: invokespecial #7; //Method java/lang/StringBuilder."<init>":()V
18: aload_1
19: getfield #2; //Field i:I
22: invokevirtual #8; //Method java/lang/StringBuilder.append:(I)Ljava/lan
g/StringBuilder;
25: ldc #9; //String ,
27: invokevirtual #10; //Method java/lang/StringBuilder.append:(Ljava/lang
/String;)Ljava/lang/StringBuilder;
30: aload_1
31: invokevirtual #11; //Method f:()I
34: invokevirtual #8; //Method java/lang/StringBuilder.append:(I)Ljava/lan
g/StringBuilder;
37: ldc #9; //String ,
39: invokevirtual #10; //Method java/lang/StringBuilder.append:(Ljava/lang
/String;)Ljava/lang/StringBuilder;
42: aload_1
43: getfield #2; //Field i:I
46: invokevirtual #8; //Method java/lang/StringBuilder.append:(I)Ljava/lan
g/StringBuilder;
49: invokevirtual #12; //Method java/lang/StringBuilder.toString:()Ljava/l
ang/String;
52: invokevirtual #13; //Method java/io/PrintStream.println:(Ljava/lang/St
ring;)V
55: return }
...
public int f(){
try{
return 1;
}finally{
return 2;
}
}
...
会return 2,原因是return之前执行finally
但是
...
public int f();
Code:
0: iconst_1
1: istore_1
2: iconst_2
3: ireturn
4: astore_2
5: iconst_2
6: ireturn
Exception table:
from to target type
0 2 4 any
4 5 4 any
...
我怎么看也觉得,是return之后,执行finally时再度return,覆盖了原先的返回值 麻烦哪位高手解释一下,谢谢
test.javapublic class test {
int i = 0; public int f() {
try {
return 1;
} finally {
return 2;
}
} public static void main(String args[]) {
testt = new test();
System.out.println(t.f());
}
}
反编译test.classimport java.io.PrintStream;public class test
{ int i; public as()
{
i = 0;
} public int f()
{
return 2;
} public static void main(String args[])
{
test t = new test();
System.out.println(t.f());
}
}
as 应该是 test
无论try块是正常结束还是强行(abruptly)
如果两块都是abruptly 那么try块中的理由就会被丢弃
java中不允许确定一定不可执行的代码的出现 如 return 后的语句
既然 finally块可以通过编译说明 finally块一定是可以执行的.当return 1 这个时候方法还没有执行完
最终执行return 2 这时第一个返回的哪个值就
会失效.
但try{}中用exit()退出时,就不会这样,finally{}不会执行。
package temporary;public class FinallyTest { /**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub for(int i=1;i<5;i++){
f(i);
}
} public static void f(int i){
System.out.println("初始化的值需要清理");
try{
System.out.println("point 1");
if(i == 1)
return;
System.out.println("point 2");
if(i == 2)
return;
System.out.println("point 3");
if(i == 3)
return;
System.out.println("End");
return;
}finally{
System.out.println("执行清理工作");
}
}
}
在一个方法中,程序可以从多个点返回,并同时可以保证重要的清理工作仍然被执行
初始化的值需要清理
point 1
执行清理工作
初始化的值需要清理
point 1
point 2
执行清理工作
初始化的值需要清理
point 1
point 2
point 3
执行清理工作
初始化的值需要清理
point 1
point 2
point 3
End
执行清理工作
try块里有return语句,那么finally语句的执行优先于return
int i=0;
public int f(){
try{
return i;
}finally{
i++;
}
}
public static void main(String args[]){
test t = new test();
System.out.println(t.i+","+t.f()+","+t.i);
}
}
代码就编译过不了呀.
f()方法必须保证返回一个int值呀
我认为是return之后执行,原因:
将下列代码反编译...
public int f(){
try{
return i;
}finally{
i++;
}
}
...得到...
public int f();
Code:
0: aload_0
1: getfield #2; //Field i:I
4: istore_1
5: aload_0
6: dup
7: getfield #2; //Field i:I
10: iconst_1
11: iadd
12: putfield #2; //Field i:I
15: iload_1
16: ireturn <<注意这里已经return了
17: astore_2
18: aload_0
19: dup
20: getfield #2; //Field i:I
23: iconst_1
24: iadd <<这里才++
25: putfield #2; //Field i:I
28: aload_2
29: athrow
Exception table:
from to target type
0 5 17 any
17 18 17 any
...但是很多人却说finally在return之前执行,为什么?
哪位高手可以解释一下?谢谢
回帖不看贴的,就免了
public static void f(int i){
System.out.println("初始化的值需要清理"); //1,6,14,24
try{
System.out.println("point 1"); //2,7,15,25
if(i == 1) //3,8,16,26
return; //5,13,23,34
System.out.println("point 2"); //9,17,27
if(i == 2) //10,18,28
return; //11
System.out.println("point 3"); //19,29
if(i == 3) //20,30
return; //21
System.out.println("End"); //31
return; //32
}finally{
System.out.println("执行清理工作"); //4,12,22,33
}
}
问return后finally里面的句子还会不会执行,什么时候执行
finally里的句子肯定会被执行 return语句之后 方法结束之前return只是给了方法一个结果 没finally那方法就结束 有finally 那就继续执行finally 方法的结果暂时放在那 finally里没再return 那方法的结果就是原来那个 再return 就覆盖掉原来那个 我想应该有个临时变量存放方法的返回结果的 return只是相当于给那个临时变量赋值以上纯个人推测 没理论依据
public class Test {
int i = 0; public int f() {
try {
return (i = returnCall());
} finally {
System.out.println("finally 里来了!");
i++;
}
}
private int returnCall(){
System.out.println("return 里来了!");
return 1001;
} public static void main(String args[]) {
Test t = new Test();
System.out.println(t.f());
}
}跟踪了一下,和楼主达成共识,是先执行return statement,后finally里的statement!
method的return和 statement的return好像是不同吧,产生歧义了,偶认为有些书写的。
*****************************************************************************
欢迎使用CSDN论坛专用阅读器 : CSDN Reader(附全部源代码) http://www.cnblogs.com/feiyun0112/archive/2006/09/20/509783.html
而是网上流传的所谓JAVA面试题之类的,所有人都信誓旦旦地说是之前,弄到我也很怀疑是不是自己搞错了再等一下,睡觉前结贴多谢各位解答
43、try {}里有一个return语句,那么紧跟在这个try后的finally {}里的code会不会被执行,什么时候被执行,在return前还是后?
会执行,在return前执行。
这里,是.NET版上的一个
http://topic.csdn.net/u/20070405/15/229f5b9a-75a0-479e-aeb3-63906c9a2dfc.html
里面4、5颗星星的人都说之前,但是都没有给出令人信服的证据
难道C#又有不同?
不过这下感觉是先执行return,执行了以后,方法并没有马上退出,而是再到finally里面去执行!public class xx { public static void main(String[] args) {
System.out.println(get());
}
public static String get() {
try {
return tt();
} catch (Exception e) {
return "";
} finally{
System.out.println("finally...");
}
}
public static String tt() {
System.out.println("ttt........");
return "ss";
}
}
以下就是根据:
见:section 12.4节。或者我在此摘录一下:A finally clause is always entered with a reason. That reason may be that the try code finished normally, that it executed a control flow statement such as return, or that an exception was thrown in code executed in the TRy block. The reason is remembered when the finally clause exits by falling out the bottom. However, if the finally block creates its own reason to leave by executing a control flow statement (such as break or return) or by throwing an exception, that reason supersedes the original one, and the original reason is forgotten. For example, consider the following code:try {
// ... do something ...
return 1;
} finally {
return 2;
}When the TRy block executes its return, the finally block is entered with the "reason" of returning the value 1. However, inside the finally block the value 2 is returned, so the initial intention is forgotten. In fact, if any of the other code in the try block had thrown an exception, the result would still be to return 2. If the finally block did not return a value but simply fell out the bottom, the "return the value 1" reason would be remembered and carried out.
主要含义是说(若不对请看原文吧):从try{}块进入到finally{},一是:try代码正常执行完或由如return语句所执行的控制流 二是:抛出异常。另外例子说明的是:当try块执行它的return 1 语句后,带着“返回值是1的'原因'”进入finally。然而,在finally内部,执行return 2,要将值2返回,因而"initial intention is forgotten"(即:原来的值被'遗忘'了),即使try块中抛出异常,返回值仍然是2.若finally中没有return语句,则"return the value 1这个'原因'"会被记住并返回值1.