2015-01-02 28 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