繁体   English   中英

为什么StringBuilder不打印?

[英]Why StringBuilder does not print?

为什么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块中)我已经为builder分配了null ,但是我的代码打印"In finally" ,然后是"JohnIbrahim" 任何人都可以向我解释这里发生了什么吗?

try块内有return语句时,它将在实际返回之前执行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;

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

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

finally块运行之前,将评估返回值并将其存储在堆栈中 请注意,堆栈上的值实际上是StringBuilder引用的值。 因此,即使您将builder设置为null ,也不会更改堆栈上已有的计算return值。 但是,如果返回值是对可变对象的引用,则可以改变对象,并且更改将在return值中可见。

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

builder.append("Hrithik Roshan");

然后你会在返回值中看到该内容。

但是,如果再次从finallyreturn builder ,它将覆盖先前计算的return语句。 但请注意,这不是一个好主意。

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

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

因此, builder = null的赋值没有任何效果,因为builder.append("Ibrahim")的评估已经在finally执行时完成。

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

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

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

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

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

}

暂无
暂无

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

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