前言
首先有如下代碼:
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。
後言
同理,其他情況我們如果發現和自己的想法有所出入時,也可以嘗試反編譯下代碼,確實能夠很直觀地幫助我們思考與解決問題。