前言
首先有如下代码:
package hpsyche.string;
/**
* @author Hpsyche
*/
public class MyTest {
static Integer count=10;
static Integer method(){
return count++;
}
public static void main(String[] args) {
System.out.println(method());
}
}
可以看到输出结果为10,结果合理,先return count,再++;
引入
再看如下例:
public class MyTest {
static Integer count=10;
static Integer method(){
try{
return count++;
}finally {
return count--;
}
}
public static void main(String[] args) {
System.out.println(method());
}
}
-
此代码的执行结果为?
11。
按照上例的思考以及对try finally执行顺序的理解:(finally是在return后面的表达式运算后执行的(此时并没有返回运算后的值,而是先把要返回的值保存起来,不管finally中的代码怎么样,返回的值都不会改变,仍然是之前保存的值),所以函数返回值是在finally执行前确定的)。
即按照我的理解,应该是先将count=10的结果保存起来,再到finally时不管其对count的任何修改,在return时直接返回count=10的结果的,但是输出结果确出人意料,为11?
让我们一探究竟,反编译字节码文件后,如下:
package hpsyche.string;
import java.io.PrintStream;
public class MyTest
{
static Integer count = Integer.valueOf(10);
static Integer method()
{
try
{
Integer localInteger1 = count;localInteger2 = MyTest.count = Integer.valueOf(count.intValue() + 1);localInteger1 = localInteger1;
}
finally
{
Integer localInteger2;
Integer localInteger3;
Integer localInteger4 = count;Integer localInteger5 = MyTest.count = Integer.valueOf(count.intValue() - 1);return localInteger4;
}
}
public static void main(String[] paramArrayOfString)
{
System.out.println(method());
}
}
其实反编译后的代码将流程写得很清楚,大家仔细看下以上代码。
个人理解:当程序看到finally中存在return时,会将try代码块中的返回值存储起来,由于try与finally中的局部变量localIntegerX不能变量,此时只能将try中count++的结果count赋予localInteger4(由于程序也不知道count到底在try中进行了什么样的变化,最终只能默认在finally中取下count的值),最后返回localInteger4(此时不管finally跑了什么代码,最后返回的都是缓存的count的值)。
所以,我们会看到最后返回值为11,而不是10。
而当finally不return时,即
package hpsyche.string;
/**
* @author Hpsyche
*/
public class MyTest {
static Integer count=10;
static Integer method(){
try{
return count++;
}finally {
count--;
}
}
public static void main(String[] args) {
System.out.println(method());
}
}
运行结果为10,
我们也尝试反编译下:
package hpsyche.string;
import java.io.PrintStream;
public class MyTest
{
static Integer count = Integer.valueOf(10);
static Integer method()
{
Integer localInteger4;
try
{
Integer localInteger1 = count;Integer localInteger2 = MyTest.count = Integer.valueOf(count.intValue() + 1);
Integer localInteger3;
return localInteger1;
}
finally
{
localInteger4 = count;Integer localInteger5 = MyTest.count = Integer.valueOf(count.intValue() - 1);
}
}
public static void main(String[] paramArrayOfString)
{
System.out.println(method());
}
}
由于finally中无返回值,缓存了try中的返回结果后执行结果后,直接在try代码块中返回,避免了第一例中try与finally无法共享局部变量的情况,此时即可以准确返回localInteger1的值,即10。
后言
同理,其他情况我们如果发现和自己的想法有所出入时,也可以尝试反编译下代码,确实能够很直观地帮助我们思考与解决问题。
371



被折叠的 条评论
为什么被折叠?



