2015-01-02 32 views
13

目前我正在代碼優化,我正在使用try ..終於阻止尊重我的對象。如何嘗試...終於內部工作

但我有困惑,如何返回一個對象的管理,當我在我的finally塊創建一個對象的空引用。 ??

在try塊中返回一個對象時,它會在編譯期間創建一個預編譯的語句嗎?或者在返回語句時在堆中創建新的引用?或者只是返回一個對象的當前引用?

以下是我的研究代碼。

public class testingFinally{ 
    public static String getMessage(){ 
     String str = ""; 
     try{ 
      str = "Hello world"; 
      System.out.println("Inside Try Block"); 
      System.out.println("Hash code of str : "+str.hashCode()); 
      return str; 
     } 
     finally { 
      System.out.println("in finally block before"); 
      str = null; 
      System.out.println("in finally block after"); 
     } 
    } 

    public static void main(String a[]){ 
     String message = getMessage(); 
     System.out.println("Message : "+message); 
     System.out.println("Hash code of message : "+message.hashCode()); 
    } 
} 

輸出是:

內部try塊
海峽的 哈希碼:-832992604

前最後bolck後
消息finally塊:你好世界
哈希碼消息:-832992604

當我看到返回對象和調用對象具有相同的哈希碼時,我感到非常驚訝。 所以我對對象引用感到困惑。

請幫我清楚這個基本。

+2

哈希碼是根據內容創建的,而不是引用地址或其他內容。那混淆是什麼? – SMA

+0

感謝您的及時回覆。我的困惑是我在我的finally塊中讓我的對象爲null。所以返回對象駐留在哪裏? – Pratik

+1

[JLS-14.20.2。執行'try-finally'和'try-catch-finally'](https://docs.oracle.com/javase/specs/jls/se7/html/jls-14.html#jls-14.20.2)可能會有助於清除你對「終於」的困惑。重要的是要注意Java'String'是不可變的。所以你已經返回了這個值的副本,你不能在最後修改返回的實例。如果你在finally中返回了一個'StringBuilder'並且調用了'setLength(0)',那麼你的調用者會得到一個零長度的'StringBuilder'。 –

回答

12

的方法並不完全返回一個對象。它返回一個對象的引用。 引用所引用的對象在方法調用內部和外部保持不變。因爲它是相同的對象,所以 哈希碼將是相同的。

return strstr的值是對字符串「Hello World」的引用。返回 語句讀取str的值並將其保存爲方法的返回值。

然後運行finally塊,它有機會通過包含自己的 return語句來更改返回值。在finally塊內更改str的值不會改變已設置的 返回值,只會有另一個返回語句。

因爲設置strnull沒有效果,所以您可以刪除像這樣的語句。只要方法返回,它就會超出範圍,因此它無助於垃圾收集。

+0

它確實對我有幫助。非常感謝。我有一個懷疑製造對象作爲null將無助於垃圾收集??。在堆空間中沒有更多的參考方法中的這種對象? – Pratik

+2

@prattpratt當方法返回時,那裏面的變量不再存在,所以它們的值不再重要。它們不會被視爲對象的引用,只要沒有其他引用存在,就可以收集它們引用的對象。 – fgb

+0

@prattpratt - 將會有一個返回地址插槽(棧頂),在這個插槽上必須推送返回的引用。所以,遇到try的返回時,「Hello World」的引用被推送到那裏。所以,無論發生什麼(重新分配對'null'的引用),都不會改變返回的*值。如果你在* finally *中調用'return str',那麼'str'的​​值將從堆棧中彈出,null將在其位置更新。所以'null'將被返回。 – TheLostMind

0

Hashcode()不用於顯示引用。相反,hashcode被用來檢查2個字符串是否彼此相等。請參閱http://docs.oracle.com/javase/6/docs/api/java/lang/String.html#hashCode()

返回此字符串的哈希碼。字符串對象的散列碼計算如下: s [0] * 31 ^(n-1)+ s [1] * 31 ^(n-2)+ ... + s [n-1]

由於兩個String都具有相同的值,當然哈希碼是相同的。

+0

即使這樣,提問者也期待'str'爲null,所以應該拋出'NullPointerException'。 –

+0

否 - Java傳遞值而不是引用。返回的值和在finally中更改的值具有不同的引用。 – Rudy

+0

是的,這就是答案。這是OP不理解的。不是如何計算哈希碼。 –

1

基礎上JLS 14.20.2 Execution of try-catch-finally

If execution of the try block completes normally, then the finally block is executed, and then there is a choice:  
    If the finally block completes normally, then the try statement completes normally. 
    If the finally block completes abruptly for reason S, then the try statement completes abruptly for reason S. 

希望這有助於:)

+0

@Downvoter我的答案有問題嗎? :) – hqt

+1

不是downVoter,但這不回答OP的問題。 – TheLostMind

+1

@TheLostMind基於他嘗試的代碼和他在帖子下的評論。 '謝謝你的及時回覆。我的困惑是我在我的finally塊中讓我的對象爲null。所以返回對象駐留的地方以及如何??我不認爲我誤解了他:) – hqt