對於程序中的以下語句,將在堆內存和字符串常量池中創建多少個對象?Java和內存管理中的對象生命週期?
我需要清晰的對象創建。我讀過的許多資料都沒有詳細說明。當對象被破壞時,我很困惑。
String a="MAM"+"BCD"+"EFG"+"GFE";
將創建多少個對象?
我正在尋找有關對象,方法和類的生命週期的良好材料,以及JVM在動態更改和修改時如何處理它們。
對於程序中的以下語句,將在堆內存和字符串常量池中創建多少個對象?Java和內存管理中的對象生命週期?
我需要清晰的對象創建。我讀過的許多資料都沒有詳細說明。當對象被破壞時,我很困惑。
String a="MAM"+"BCD"+"EFG"+"GFE";
將創建多少個對象?
我正在尋找有關對象,方法和類的生命週期的良好材料,以及JVM在動態更改和修改時如何處理它們。
只有一個對象被創建並放置在常量池中,除非它已經存在,在這種情況下使用現有對象。編譯器將字符串常量連接在一起,如JLS 3.10.5和15.28中所指定。
長字符串文字總是可以被分成較短的段,並使用字符串連接運算符寫成(可能括號內)的表達+
http://docs.oracle.com/javase/specs/jls/se7/html/jls-3.html#jls-3.10.5
只創建一個對象。
string s1 = "java";
string s2 = "ja" + "va";
s.o.p(s1==s2);
該聲明爲真。
String s1="java";
string s2 = "ja";
String s3 = s2 +"va";
s.o.p(s1==s3);
該聲明產生錯誤。因此,最小的一個顯然應該是永久的,然後'+'操作符使用new()在非常量池中生成新的字符串對象。 所以,你問的問題沒有一個也是永久性的。這意味着它只創建一個對象。
"MAM"+"BCD"+"EFG"+"GFE"
是編譯時常量表達式並將其編譯爲"MAMBCDEFGGFE"
字符串文字。當加載包含上述代碼的類時,JVM將從該文字創建一個String
的實例,並將此String
放入字符串池中。因此String a = "MAM"+"BCD"+"EFG"+"GFE";
不創建任何對象,請參閱JLS 15.18.1. String Concatenation Operator +
String對象是新創建(§12.5),除非表達是一個編譯時間常量表達式(§15.28)。
它只是將對池中String
對象的引用分配給本地變量a
。
我現在得到了這個概念謝謝@Evgeniy – saikiran
由於String a
會編譯成"MAMBCDEFGGFE"
,因此只會創建一個對象。
在您的示例中指出單個堆對象的答案是正確的。但是,請考慮以下代碼:
public class Tester
{
public String a="MAM";
public String b ="BCD";
public String c = "EFG";
public String d ="GFE";
public Tester()
{
String abcd = a + b + c + d;
}
}
在此示例中,創建了7個字符串。 a,b,c和d不會被編譯成一個常量 - 它們是成員。然後爲每個+
運算符創建1個字符串 - 從語義上講,+
是一個串聯,但從邏輯上說,它正在內存中創建一個新字符串。前2個運算符字符串會立即丟棄,現在可以進行垃圾回收了,但內存流失仍然存在。
技術上存在於第8個對象中。 Tester的實例。
編輯:這已經被證明是無稽之談在評論
大多數的答案似乎把重點在於:a)完整的表達是一個編譯時間常數和b)該行本身並不構建一個新的對象,但只有一個參考一個對象。
但是迄今爲止沒有人提到過,String
本身包含對內部char[]
(它也在常量池中)的引用。
摘要:常量池中有兩個對象(String
和char[]
)。該行既不創建也不銷燬任何對象。
以及有關:
我很困惑,當對象被銷燬。
沒有對象被銷燬,因爲常量池中的東西只會在類本身被卸載時被銷燬。最多可以說,參考文獻a
最終會超出範圍。
您怎麼看? –
有人應該在其上運行'javah'。我敢打賭它只會顯示一個常數。 – Rekin
upto我只有一個,但很多朋友在這個討論困惑我 [鏈接](https://www.facebook.com/groups/java.for.developers/10151748401034501/?notif_t=group_comment_reply) – saikiran