try finally中return count++等情況下,返回值的理解

前言

首先有如下代碼:

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。

後言

同理,其他情況我們如果發現和自己的想法有所出入時,也可以嘗試反編譯下代碼,確實能夠很直觀地幫助我們思考與解決問題。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章