发现此问题here
我无法理解,为什么在第一种情况下打印CoolReturn+1
和第二种情况CoolReturn
?它是如何工作的?
由于
====================
会打印什么?
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.append("+1");
}
}
答案:CoolReturn + 1
有点困难:
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
答案 0 :(得分:7)
考虑
protected StringBuilder setOne(){
StringBuilder builder=new StringBuilder();
try{
builder.append("Cool");
return builder.append("Return");
}finally{
builder.append("+1");
}
}
作为
protected StringBuilder setOne(){
StringBuilder builder=new StringBuilder();
try{
builder.append("Cool");
StringBuilder ret = builder.append("Return"); // 1
return ret; // 2
}finally{
builder.append("+1"); //3
}
}
执行第1行,结果返回builder
。然后执行第3行,builder
附加+1
,然后返回ret
,这是builder
引用的对象的“引用”。第二种情况也是如此。希望很清楚。
答案 1 :(得分:6)
第一个:
终于总会开火(假设机动车没有碰撞或任何事情)。因此,在返回之后,finally块将触发,并且由于它具有对象“builder”的引用,因此它会将额外的标记附加到它。
第二个:
finally块像以前一样触发,但它将对builder的引用设置为null。该对象仍然存在,因为它仍然有一个链接。
答案 2 :(得分:2)
当它返回builder.append(“返回”)时,对构建器变量的引用的副本被压入堆栈。然后构建器设置为null。然后调用者将引用的副本从堆栈中弹出。
答案 3 :(得分:1)
在第一个示例中,在finally块中,您使用append操作字符串构建器。
在第二个示例中,在finally块中,在从append方法返回结果后,将指向字符串构建器的指针更改为空指针。这不会修改您以前以任何方式指向的字符串构建器。
编辑:看起来我很受欢迎。答案 4 :(得分:0)
finally运算符始终运行,因此返回构建器,然后返回+1。
在第二个上,构建器设置为null,因此没有其他内容可以添加到它。在最后一个中,它可以很容易地成为builder =“”。
答案 5 :(得分:0)
finally块将始终执行。 http://download.oracle.com/javase/tutorial/essential/exceptions/finally.html这就是为什么所有三个陈述都要追加。
答案 6 :(得分:0)
这是有效的,因为return
表达式是在执行finally
块之前计算的。当您在代码的return
语句中调用方法并将日志记录语句添加到try
和finally
块时,这一点非常明显。相关的解释可以在JLS 3rd edition, 14.20.2中找到。这是return
块中的finally
语句在IDE中像Eclipse一样产生警告的原因之一。
示例groovy代码:
def doSomething() {
def f = "something";
try {
return f += doSomethingMore()
} finally {
println "before nulling";
f = null;
println "after nulling";
}
}
def doSomethingMore() {
println "doSomethingMore called"
return "-wow";
}
println "output from call ---> " + doSomething()