[英]What is happening when you “alter” a string in Java using “+=”?
我了解Java中的String變量是不可變的,因此無法更改。
String myString = "Hello.";
myString += " ";
myString += "My name is Kevin";
每次我們向此String()
添加一些東西時,我們實際上都是在創建一個新的String()
,但這與要連接的字符串具有相同的名稱。 這是否意味着內存中有多個變量為“ myString”的引用?
每次“修改” /級聯這些String
與+=
,你要創建一個新的String
對象,並更換指定的參考myString
與新創建的String
。 因此,沒有,內存中只有一個引用,但是引用指向的對象每次都會更改。 字符串是不可變的 ,因此無法“就地”修改對象。
字符串是Java中不變的類。 不可變類只是其實例無法修改的類。 創建實例時實例中的所有信息都會初始化,並且無法修改該信息。 不變類有很多優點。
在程序員的StackExchange上有一個很好的答案,它解釋了 String
在Java中為什么不可變的原因 ,以及有關其工作原理的更多詳細信息。
最好的方法是只使用StringBuilder()
類:
String myStringBuilder = new StringBuilder("Hello.");
myStringBuilder.append(" ");
myStringBuilder.append("My name is Kevin");
System.out.println(myStringBuilder.toString());
但是,現代Java編譯器會自動將String
串聯轉換為StringBuilder
操作。
不,您無法訪問以前的參考,垃圾收集器留了它來收集它。 換句話說,內存中只有一個引用可以保存變量的當前值(“我的名字叫凱文”)
請注意,如果要大量更改String變量,則應使用StringBuilder類。
這是StringBuilder類文檔的鏈接,您也可以找到很多在互聯網上使用此類的示例
https://docs.oracle.com/javase/8/docs/api/java/lang/StringBuilder.html
這也是您問題的詳細答案
String myString = "Hello.";
上面創建了一個新的Object
並放置了"Hello."
將myString
引用到Object
到內存中。
myString += " ";
在這里,您可以將其顯示為myString = myString + " ";
創建一個" "
字符串並放入內存中,並置后將創建一個由myString
引用的新String
。
請注意,帶有"+"
字符串連接的復雜度為O(N2),而StringBuilder
復雜度為O(N)。 假設每次都為連接結果創建新的String
,而StringBuilder
卻包含一個字符序列。 因此, String
連接比使用StringBuilder
效率低,特別是需要構建大量的String時。
Java使用字符串池。 這是字符串實習概念的實現。
在計算機科學中,字符串插入是一種僅存儲每個不可變字符串值的一個副本的方法,該值必須是不變的。 內聯字符串使某些字符串處理任務更加節省時間或空間,但代價是在創建或內聯字符串時需要更多時間。 不同的值存儲在字符串內部存儲池中。
這意味着對於每個字符串,都將特定字符串的副本添加到字符串池中。 包含該確切字符串的每個變量都指向字符串池中的該副本。
字符串Hello.
, ,並且
My name is Kevin
被添加到字符串池中,因為它們是程序中的文字。
String myString = "Hello.";
變量myString
開始指向字符串Hello.
,它已經在字符串池中。
myString += " ";
字符串Hello.
(請注意最后的額外空間)已添加到池中。 變量myString
現在指向該變量。
myString += "My name is Kevin";
字符串Hello. My name is Kevin
Hello. My name is Kevin
被添加到泳池中。 變量myString
現在指向該變量。
池中不再被變量引用的字符串可以進行垃圾回收 ,因此Hello.
(末尾有空格),現在可以進行垃圾收集。
在這里,您可以在其中定義String
引用變量myString
。
字符串是一個不可變的類,它意味着一旦創建,就不能在對象上進行任何修改。
在這里, "Hello"
創建一個String對象,並通過myString引用該對象。
String myString = "Hello."; //create a Object String contain Hello and refer to myString
myString += " ";
myString += "My name is Kevin";
當myString+=" ";
被執行后,它會通過在其中插入“ Hello”來創建String的另一個新對象。
"Hello "
創建了一個新對象,而myString引用了它。 "Hello"
有資格進行垃圾回收。
再次當myString += "My name is Kevin";
被執行后,它會通過在其中填充"Hello "
來創建另一個新的String對象。 您的新對象"Hello My Name is Kevin"
由字符串類型的myString引用變量引用。
現在,您的早期對象
"Hello"
和"Hello/s"
都沒有被任何其他引用變量引用,因此,它可以進行垃圾回收。
謝謝
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.