为什么StringBuilder不打印?

时间:2013-08-04 12:29:19

标签: java stringbuilder

为什么StringBuilder不打印它应该用小代码打印的内容

public final class Test1 {

    public void test() {
        System.out.println(setFin().toString());
    }

    protected StringBuilder setFin() {
        StringBuilder builder = new StringBuilder();
        try {
            builder.append("John");
            return builder.append("Ibrahim");
        } finally {
            System.out.println("In finaly");  // builder.append("-DarElBeida");
            builder = null;
        }
    }     

    public static void main(String args[]){
        new Test1().test();
    }
}

setFin()finally区块)中执行的最后一个语句中,我已将null分配给builder,但我的代码打印为"In finally",然后"JohnIbrahim"。任何人都可以向我解释这里发生了什么吗?

6 个答案:

答案 0 :(得分:5)

return块内有try语句时,它会在实际返回之前执行finally块。

该方法不返回null,因为return语句包含对实际 StringBuilder 对象的引用,而不是对变量builder的引用。

设置builder == null不会删除 StringBuilder 本身,只会删除builder对它的引用。

这种行为可能令人困惑。为了清楚起见,从try / catch / finally块外部返回可能会有所帮助:

StringBuilder builder = new StringBuilder();

try {
    builder.append("John");
    builder.append("Ibrahim");
} finally {
    System.out.println("In finaly");  // builder.append("-DarElBeida");
    builder = null;
}

return builder;

答案 1 :(得分:3)

您将返回builder。之后,将builder设置为null。但它已经归还了。之后你对变量做了什么并不重要。返回值已经“锁定”。你能做的就是弄乱正在返回的对象。例如,builder.setLength(0)会删除所有文字。

从理论上讲,您也可以从finally块中return null,但强烈建议不要这样做(更改返回值)。

答案 2 :(得分:3)

finally块运行之前,

返回值被评估并存储在堆栈中。请注意,堆栈上的值实际上是StringBuilder引用的值。因此,即使您将builder设置为null,也不会更改已在堆栈上的已评估return值。但是,如果返回值是对可变对象的引用,则可以改变对象,并且更改将在return值中显示。

例如,如果您在finally块中添加以下语句而不是nullifying引用:

builder.append("Hrithik Roshan");

然后您将在返回值中看到该内容。

但是,如果return builder再次finally阻止,则会覆盖先前评估的return语句。但请注意,这不是一个好主意。

答案 3 :(得分:2)

始终执行

finally,除非JVM在try块完成之前崩溃或退出。

如果try块由于return语句而完成,则return的表达式在 {{1}之前被评估为单个值块执行。该值将被保存,并在finally块完成时返回。

因此,finally的分配无效,因为builder = null的评估已在builder.append("Ibrahim")执行时完成。

答案 4 :(得分:1)

builder包含对您创建的StringBuilder的引用。执行builder = null后,您将builder设置为不再保留该引用。 StringBuilder本身仍然存在(至少在垃圾收集发生之前)。

正在发生的事情是你的return语句正在返回对StringBuilder的引用。 返回变量builder;它返回对builder引用的事物的引用。因此,即使您正在消除变量,return语句也已经引用了创建的对象。

如果您在builder块中打印finally,那么它将为空。

答案 5 :(得分:0)

执行return的第一个执行builder.append("Ibrahim")语句,该语句返回StringBuilder的引用。引用被保存到堆栈中。然后执行了finally块。您已经取消了局部变量,但在方法实际返回后,对StringBuilder对象的引用传递给调用者。这就是打印所有值的原因。错误是您为builder块中从未使用过的finally分配了一个值。堆栈在实际返回之前保留return语句操作数的值,即在finally块之后。如果您不希望从return null块中的finally方法返回引用,那将覆盖堆栈中的值。

} finally {
  System.out.println("In finaly");  // builder.append("-DarElBeida");
  return null;

}