![](/img/trans.png)
[英]Why does StringBuffer/StringBuilder not override equals or hashCode?
[英]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");
然后你會在返回值中看到該內容。
但是,如果再次從finally
塊return
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.