try/catch/finally语句下,finally子句是肯定会执行的。但是很多人做不同的测试,却得出了不同的结论。
具体的原理最好是去看《深入java虚拟机》,里面对jsr、ret等几个指令做了详细的说明。这里不深入分析,而仅仅是从表现形式上看一下finally的特征。
代码:
/*
* author: Zang XT
*/
public class TestFinal {
public static void main(String[] args) {
System.out.println("test1:"+testFinal1());
System.out.println("test2:"+testFinal2());
System.out.println("test3:"+testFinal3());
System.out.println("test4:"+testFinal4());
}
static int testFinal1(){
int i = 1;
try{
return i;
}
finally{
System.out.println("in testFinal1():finally 肯定会被执行的!");
i = 48;
}
}
static String testFinal2(){
String str = "try";
try{
return str;
}
finally{
System.out.println("in testFinal2():finally 肯定会被执行的!");
str = "finally";
}
}
static StringBuilder testFinal3(){
StringBuilder build = new StringBuilder("try ");
try{
return build;
}
finally{
System.out.println("in testFinal3():finally 肯定会被执行的!");
build.append("finally");
build = new StringBuilder("你猜我是谁!");
}
}
static String testFinal4(){
try{
return "return in try";
}
finally{
System.out.println("in testFinal4():finally 肯定会被执行的!");
return "return in finally";
}
}
}
输出是:
in testFinal1():finally 肯定会被执行的!
test1:1
in testFinal2():finally 肯定会被执行的!
test2:try
in testFinal3():finally 肯定会被执行的!
test3:try finally
in testFinal4():finally 肯定会被执行的!
test4:return in finally
结论很明显,finally的语句确实执行了,而且肯定是在方法return之前执行的,而且,如果finally中有return语句的话,方法直接结束。这里需要注意的只有一点:在try中的return语句会将返回结果值压栈,然后转入到finally子过程,等到finally子过程执行完毕之后(没有return),再返回。
下面具体看4个例子:
在testFinal1()中,return i;会将结果i的值,也就是1压入栈。即使在finally中将i修改了(i=48),也不回对已经压入栈里的1造成任何影响。
在testFinal2()中,return str;将str的内容压入栈,比如我们假设str的内容为0x108(只是一个地址值),通过这个地址值我们能找到"try",那栈里的内容就是0x108。执行str = "finally",这时候str这个变量的内容可能变为0x237了,这是串"finally"的地址。方法调用结束后,返回的是什么?return时压入栈里的0x108。所以在打印结果时,我们打印的是通过0x108找到的字符串"try"。
在testFinal3()中,return 压栈的是build这个变量的值,比如是0x3579,通过这个值我们可以找到StringBuilder对象。finally语句块中对这个对象的内容进行了修改。build = new StringBuilder("你猜我是谁!");让build变量指向了一个新的对象,这时候build的值可能是0x4579了。但是,别忘了,原来的StringBuilder对象仍然在0x3579处,而我们压栈的正是0x3579啊!方法返回后,我们得到的返回值0x3579,通过这个引用值找到相应的StringBuilder对象,所以打印的结果是test3:try finally。
在testFinal4()中,finally有return语句,直接返回,方法结束。
为什么不同的人有不同的结论?关键是没有正确理解压栈的是什么东西。其实初学java的时候,如果理解了变量是什么,并区分引用和对象本身就不会得到错误的结论了。再有,如果理解java中,方法调用都是采用传值模式的话,这里也就类似的可以明白了。
分享到:
相关推荐
在Java的异常机制中,如果finally中含有return语句,则try和catch中的return语句将会被JVM忽视
try、catch、finally、return 执行顺序超详细讲解,包看包会。
Condition 3: try中有异常,try-catch-finally里都没有return ,finally 之后有个returntry中有异常以后,根据
第二:finally里面不建议放return语句,根据需要,return语句可以放在try和catch里面和函数的后。可行的做法有四: 1、return语句只在函数后出现一次。 2、return语句仅在try和catch里面都出现。 3、...
try-catch-finally执行顺序验证(左边是.java文件,右边是.class文件) 提示: try、catch块内的return操作编译后会变成把return的值保存到变量var的操作。 总结: try、catch块内的return操作编译后会变成把return的值...
The production IfStatement : if ( Expression ) Statement else Statement is evaluated as follows:.
我们知道return语句用在某一个方法中,一是用于返回函数的执行结果,二是用于返回值为void类型的函数中,仅仅是一个return语句(return ;),此时用于结束方法的执行,也即此return后的语句将不会被执行,当然,这种...
首先执行try,如果有异常执行catch,无论如何都会执行finally,当有return以后,函数就会把这个数据存储在某个位置,然后告诉主函数,我不执行了,接下来你执行吧,所以函数就会推出
Java finally语句到底是在return之前还是之后执行?Java finally执行深度剖析,具体看这篇博文:http://blog.csdn.net/lanxuezaipiao/article/details/16922895,这是里面相关的源码,欢迎大家下载使用。
finally 一定会被执行,如果 finally 里有 return 语句,则覆盖 try/catch 里的 return , 比较爱考的是 finally 里没有 return 语句,这时虽然 finally 里对 return 的值进行了修改,但 return 的值并不改变这种...
} finally { try { is.close(); } catch (Exception e) { } } url = infos.getProperty(URL); } public static Connection getConnection() { try { return DriverManager.getConnection...
在一个try………end try 过程中可以使用catch与finally两个中的一 个,或者两个一起用, 二:Protected, private, Public 封装控制 这三个关键字一般放在语句最前面,而会置于overloads与Overrides的 后面...
catch (Exception e) { throw new Exception("数据库连接出现错误!"); } finally { //主动销毁资源 cmd.Dispose(); // 关闭连接 con.Close(); } } } catch (Exception e) { // MessageBox.Show(e....
- 无论try是否发生异常,finally语句都会执行- 如果try/catch中包含控制转移语句(return、continue、break),finally
} finally { // 下面省略关闭的详细代码,只简单示意一下 try { if (rs != null) { rs.close(); } if (pstmt != null) { pstmt.close(); } if (cn != null) { cn.close(); } } catch (SQLException e) ...
return Convert.ToInt32(res) > 0; } public static int GetMaxID(string FieldName, string TableName) { string strsql = "select max(" + FieldName + ")+1 from " + TableName; object obj = GetSingle...
finally { tDESkey.Clear(); } return xmlDoc; } //加密XML public static bool WriteFileXML(string mFilePath) { bool success = true; XmlDocument xmlDoc = new XmlDocument(); try { xmlDoc....
try { Fsm = File.OpenRead(filename); return this.ConvertStreamToByteBuffer(Fsm); } catch { return new byte[0]; } finally { Fsm.Close(); } } else { return new byte[0]; } }
1. try的意思,就是试着...4. 如果在try或者catch之中,执行System.exit(0); 那么 finally不会被执行,此外的情况,不管是Error还是return,finally块都会执行到。 5. 建议不清楚的拷贝代码或者自己写一份执行了看看。
catch (ThreadStateException) { } finally { senderThread = null; } } if (udpClient != null) { udpClient.Close(); udpClient = null; } } disposed = true; } } #...