简体   繁体   English

尝试/最后阻止问题

[英]try / finally block question

Found this question here 在这里找到这个问题

And I can't understand, why on first case it prints CoolReturn+1 and on second case CoolReturn ? 我无法理解,为什么在第一种情况下它打印CoolReturn+1和第二种情况CoolReturn How does it work? 它是如何工作的?

Thanks 谢谢

==================== ====================

What will be printed? 什么会打印?

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");
    }
}

Answer: CoolReturn+1 答案:CoolReturn + 1

A bit more difficult: 有点困难:

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;  /* ;) */
    }
}

Answer: CoolReturn 答:CoolReturn

Consider 考虑

protected StringBuilder setOne(){
    StringBuilder builder=new StringBuilder();
    try{
        builder.append("Cool");
        return builder.append("Return");
    }finally{
        builder.append("+1");
    }
}

as

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
    }
}

line 1 is executed, the builder is returned as result. 执行第1行,结果返回builder Then line 3 is executed, and the builder gets appended by +1 , then the ret is returned which is a "reference" to the object referenced by builder . 然后执行第3行,并且builder附加+1 ,然后返回ret ,它是builder引用的对象的“引用”。 The same is for the second case. 第二种情况也是如此。 Hope it is clear. 希望很清楚。

The first one: 第一个:

The finally will always fire (assuming the machien doesn't crash or anything). 终于总会开火(假设机器没有崩溃或任何事情)。 So after the return, the finally block fires, and since it has a reference to the object "builder", it appends the extra token to it. 因此,在返回之后,finally块将触发,并且由于它具有对象“builder”的引用,因此它会将额外的标记附加到它。

The second one: 第二个:

The finally block fires just like before, but it sets the reference to builder to be null. finally块像以前一样触发,但它将对builder的引用设置为null。 The object still exists, because it still has a link to it. 该对象仍然存在,因为它仍然有一个链接。

When it does return builder.append("Return") a copy of the reference to the builder variable is pushed onto the stack. 当它返回builder.append(“返回”)时,对构建器变量的引用的副本将被压入堆栈。 Then builder is set to null. 然后构建器设置为null。 The caller then pops the copy of the reference off the stack. 然后调用者从堆栈中弹出引用的副本。

In the first example, in the finally block, you manipulate the string builder with append. 在第一个示例中,在finally块中,您使用append操作字符串构建器。

In the second example, in the finally block, you change your pointer to the string builder to be the null pointer, after you return the result from the append method. 在第二个示例中,在finally块中,在从append方法返回结果后,将指向字符串构建器的指针更改为空指针。 This does not modify the string builder that you formerly pointed to in any way. 这不会修改您以前以任何方式指向的字符串构建器。

EDIT: Looks like I got beat to it. 编辑:看起来我被击败了。

The finally operator always runs so builder gets returned and then the +1 is returned. finally运算符始终运行,因此返回构建器,然后返回+1。

On the second one, the builder is set to null, so there is nothing else to add to it. 在第二个,构建器设置为null,因此没有其他任何内容可以添加到它。 It could just as easily be builder = "" in the last one. 在最后一个中,它可以很容易地成为builder =“”。

The finally block will always execute. finally块将始终执行。 http://download.oracle.com/javase/tutorial/essential/exceptions/finally.html Thats why all three statements are appending. http://download.oracle.com/javase/tutorial/essential/exceptions/finally.html这就是为什么要附加所有三个语句的原因。

This works because the return expression is evaluated before the finally block is executed. 这是有效的,因为在执行finally块之前会计算return表达式。 This is pretty apparent when you invoke a method in the return statement of your code and add logging statements to your try and finally blocks. 当您在代码的return语句中调用方法并将日志语句添加到tryfinally块时,这一点非常明显。 The relevant explanation can be found in the JLS 3rd edition, 14.20.2 . 相关的解释可以在JLS第3版,14.20.2中找到 This is one of the reasons why return statements in the finally block produce a warning in IDE's like Eclipse. 这就是为什么finally块中的return语句在IDE中像Eclipse一样产生警告的原因之一。

A sample groovy code: 样本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()

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM