簡體   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