Java 对象引用在finally块中设置为null

Java 对象引用在finally块中设置为null,java,finally,try-finally,Java,Finally,Try Finally,为什么输出是CoolReturn而不是null 问候, Mahendra Athneria表达式在return语句中计算为一个值,该值将被返回。finally块在return语句的表达式求值部分之后执行 当然,finally块可以修改返回值引用的对象的内容,例如: public void testFinally(){ System.out.println(setOne().toString()); } protected StringBuilder setOne(){ StringBuild

为什么输出是CoolReturn而不是null

问候,

Mahendra Athneria

表达式在return语句中计算为一个值,该值将被返回。finally块在return语句的表达式求值部分之后执行

当然,finally块可以修改返回值引用的对象的内容,例如:

public void testFinally(){
System.out.println(setOne().toString());

}

protected StringBuilder setOne(){
StringBuilder builder=new StringBuilder();
try{
builder.append("Cool");
return builder.append("Return");
}finally{
builder=null; /* ;) */
}
}

在这种情况下,控制台输出将是“CoolReturn I get the last laugh!”——但它不能更改实际返回的值。

最终块用于执行try块后的“清理”。由于您已返回引用,因此不能以这种方式更改它

显然,它看起来应该为null,但在java中,通过引用传递的概念,它是如何运行的:

1> return
builder.append(“return”)
。。。执行第行,并通过pass-by-reference将builder引用的副本返回给testFinally()方法


2> 在最后执行中的
builder=null
时,会取消对builder引用的引用,但堆中先前由builder引用的实际对象仍然存在于堆中,并且返回了构建器引用的副本(这也是指向同一对象的引用)仍然存在,并且保留值“CoolReturn”,这就是它打印返回值的原因。

我认为这有点误导——例如,如果finally块抛出异常,它最终仍会被抛出。我认为将返回值的计算(发生在finally块之前)分离出来更为清晰然后将控制权从方法转移回调用方(发生在finally块之后)。你是对的,我将更改我的措辞。但是你的答案是好的;-)@Jon,但是为什么
builder.append(“某些值”)修改实际返回值,而
builder=null
不是?@Darin:因为
builder
是一个引用。将引用设置为null会取消对所述引用的设置,但它引用的对象在被垃圾回收之前仍然存在<另一方面,code>append
修改对象(或其属性之一)@Darin:append方法返回调用它的变量的链接。所以返回builder.append(“某些值”);实际上,将“某个值”附加到生成器,并将指向生成器的链接作为对象返回,您可以在finally块中更改该链接。当您编写builder=null时,您只需更改builder点的位置,而不是位于旧链接下的值。@Maxym-正如您在编写builder=null时所说,我们只是更改builder点。我同意了。但作为回报,我们返回引用,现在它引用null。因此,它应该使用新引用所指向的值。我清楚了吗?@Mahendra您计算了这个引用作为回报…,您不能仅仅通过更改生成器变量指针来更改它。您可以在finally块中写入“return…”,然后可以返回另一个对象
finally {
  builder.append(" I get the last laugh!");
}