简体   繁体   English

为什么StringBuilder不打印?

[英]Why StringBuilder does not print?

Why StringBuilder does not print what it should print in a small code 为什么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();
    }
}

In the last statement executed in setFin() (in the finally block) I have assigned null to builder , but my code prints "In finally" and then "JohnIbrahim" . setFin()执行的最后一个语句(在finally块中)我已经为builder分配了null ,但是我的代码打印"In finally" ,然后是"JohnIbrahim" Can anybody explain to me what is going on here? 任何人都可以向我解释这里发生了什么吗?

When there is a return statement inside the try block, it will execute the finally block before actually returning. try块内有return语句时,它将在实际返回之前执行finally块。

And the method doesn't return null because the return statement holds a reference to the actual StringBuilder object, not to the variable builder . 并且该方法不返回null因为return语句包含对实际StringBuilder对象的引用,而不是对变量builder的引用。

Setting builder == null doesn't delete the StringBuilder itself, it just drops builder 's reference to it. 设置builder == null不会删除StringBuilder本身,它只是删除了builder对它的引用。

This behavior can be confusing. 这种行为可能令人困惑。 To make things clear it could be helpful to return from outside the try/catch/finally block: 为了清楚起见,从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;

You are returning builder . 你正在回归builder After that you set builder to null. 之后,将builder设置为null。 But it has already been returned. 但它已经归还了。 It does not matter what you do to the variable afterwards. 之后你对变量做了什么并不重要。 The return value is already "locked-in". 返回值已经“锁定”。 What you could do is mess with the object that is being returned. 你能做的就是弄乱正在返回的对象。 For example, builder.setLength(0) will remove all text to it. 例如, builder.setLength(0)将删除所有文本。

In theory, you could also return null from the finally block, but that (changing the return value) is highly discouraged. 从理论上讲,您也可以从finally块return null ,但强烈建议不要(更改返回值)。

Return value is evaluated and stored on the stack , before the finally block runs. finally块运行之前,将评估返回值并将其存储在堆栈中 Note that the value on the stack is actually the value of the StringBuilder reference. 请注意,堆栈上的值实际上是StringBuilder引用的值。 So, even if you set the builder to null , that doesn't changes the evaluated return value already on the stack. 因此,即使您将builder设置为null ,也不会更改堆栈上已有的计算return值。 However, if the return value is a reference to an mutable object, you can mutate the object, and the changes will be visible in return value. 但是,如果返回值是对可变对象的引用,则可以改变对象,并且更改将在return值中可见。

For eg, if you add the below statement in the finally block instead of nullifying the reference: 例如,如果在finally块中添加以下语句而不是nullifying引用nullifying

builder.append("Hrithik Roshan");

then you will see that content in the return value. 然后你会在返回值中看到该内容。

However, if you return the builder again, from finally block, it will overright the previous evaluated return statement. 但是,如果再次从finallyreturn builder ,它将覆盖先前计算的return语句。 But mind you it's not a good idea. 但请注意,这不是一个好主意。

finally is always executed, unless the JVM crashes or exits before the try block finishes. finally总是执行,除非JVM在try块完成之前崩溃或退出。

If the try block completes due to a return statement, the expression of the return is evaluated into a single value before the finally block executes. 如果try块由于return语句而完成,则在finally块执行之前 ,将return的表达式计算为单个值。 That value is saved, and returned when the finally block completes. 该值被保存,并在finally块完成时返回。

Thus, the assignment of builder = null has no effect because the evaluation of builder.append("Ibrahim") is already finished by the time the finally executes. 因此, builder = null的赋值没有任何效果,因为builder.append("Ibrahim")的评估已经在finally执行时完成。

builder holds a reference to the StringBuilder that you've created. builder包含对您创建的StringBuilder的引用。 When you do builder = null , you're setting builder to no longer hold that reference. 当您执行builder = null ,您将builder设置为不再保留该引用。 The StringBuilder itself still exists (at least until garbage collection occurs). StringBuilder本身仍然存在(至少在垃圾收集发生之前)。

What's happening is that your return statement is returning a reference to the StringBuilder. 发生的事情是你的return语句返回对StringBuilder的引用。 It's not returning the variable builder ; 没有返回变量builder ; it's returning a reference to the thing that builder refers to. 它返回对builder引用的东西的引用。 So even though you're wiping out the variable, the return statement already has a reference to the created object. 因此,即使您正在消除变量,return语句也已经引用了创建的对象。

If you printed builder in your finally block, it would be null there. 如果在finally块中打印了builder ,那么它将为null。

First executed return statement which execute builder.append("Ibrahim") that returns the reference of StringBuilder . 第一个执行的return语句,它执行返回StringBuilder引用的builder.append("Ibrahim") The referece is saved to the stack. 引用被保存到堆栈中。 Then excuted the finally block. 然后执行了finally阻止。 You have nulled the local variable, but the reference to StringBuilder object passed to the caller after the method actually return. 您已经取消了局部变量,但在方法实际返回后, StringBuilder对象的引用传递给调用者。 That's why printed all values. 这就是打印所有值的原因。 The error is that you assign a value to the builder in finally block that is never used. 错误是您为finally块中的builder分配了一个从未使用过的值。 The stack keeps the value of the return statement operand before it actually returned, ie after finally block. 堆栈在实际返回之前保持return语句操作数的值,即在finally块之后。 If you don't want to return reference from the method you should return null in the finally block, that will override the value in the stack. 如果您不想从方法返回引用,则应在finally块中return null ,这将覆盖堆栈中的值。

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

}

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

相关问题 为什么StringBuffer / StringBuilder不覆盖equals或hashCode? - Why does StringBuffer/StringBuilder not override equals or hashCode? 为什么更改 StringBuilder 会更改其 hashCode? - Why does changing StringBuilder change its hashCode? 返回或打印 StringBuilder? 爪哇 - Return or Print StringBuilder? Java 为什么Oracle Java编译器更喜欢no-args StringBuilder构造函数? - Why does the Oracle Java compiler prefer the no-args StringBuilder constructor? 为什么new StringBuffer(new StringBuilder(“ foo”))可以工作? - Why new StringBuffer(new StringBuilder(“foo”)) does work? 为什么在检查回文时这个反转的 StringBuilder 不等于原始字符串? - Why does this reversed StringBuilder not equal the original String when checking for a Palindrome? 为什么.toString()似乎修复了StringBuilder的OutOfMemoryError异常? - Why does .toString() seem to fix an OutOfMemoryError exception for StringBuilder? 为什么Java StringBuilder有CharSequence的构造函数和String的另一个构造函数? - Why does Java StringBuilder have a constructor for CharSequence and another one for String? 在带有换行符的 TextArea 上打印 StringBuilder - Print a StringBuilder on a TextArea with line break StringBuilder是否不附加空格? - Does StringBuilder not append whitespaces?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM