Java 为什么StringBuilder不打印?

Java 为什么StringBuilder不打印?,java,stringbuilder,Java,Stringbuilder,为什么StringBuilder不在小代码中打印它应该打印的内容 public final class Test1 { public void test() { System.out.println(setFin().toString()); } protected StringBuilder setFin() { StringBuilder builder = new StringBuilder(); try {

为什么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
,但我的代码在finally中打印
,然后打印
“JohnIbrahim”
。有人能解释一下这里发生了什么吗?

try
块中有
return
语句时,它将在实际返回之前执行
最后的

并且该方法不会返回
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块
返回null
,但这(更改返回值)是非常不可取的。

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

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

builder.append("Hrithik Roshan");
然后您将在返回值中看到该内容


但是,如果您再次从
finally
返回
生成器
,它将覆盖先前计算的
return
语句。但请注意,这不是一个好主意。

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

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


因此,
builder=null
的赋值无效,因为
builder.append(“Ibrahim”)
的求值在
最终执行时已经完成。

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

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


如果在
finally
块中打印
builder
,则该块将为空。

第一次执行
return
语句,该语句执行
builder.append(“Ibrahim”)
,返回
StringBuilder
的引用。引用将保存到堆栈中。然后执行
最后
块。您已将局部变量置零,但在方法实际返回后,对
StringBuilder
对象的引用传递给调用方。这就是为什么要打印所有值。错误在于,您为
finally
块中的
生成器
指定了一个从未使用过的值。堆栈将
返回
语句操作数的值保留在实际返回之前,即
最终
块之后。如果不想从方法返回引用,则应在
finally
块中
returnnull
,这将覆盖堆栈中的值

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

}

我认为OP对它为什么不打印
null
感到困惑。我认为困惑在于它为什么不打印
null
(你的陈述没有真正解释这一点-如果
builder=null
是“在返回之前评估的”,那么它“应该返回null”),这是糟糕的代码。也许,你只是想读书