尝试/最后阻止问题

时间:2011-03-29 18:48:00

标签: java try-catch

发现此问题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

7 个答案:

答案 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语句中调用方法并将日志记录语句添加到tryfinally块时,这一点非常明显。相关的解释可以在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()