回答
你的字符串變量不是字符串。這是一個String實例的參考。
見自己:
String str = "Test String";
System.out.println(System.identityHashCode(str)); // INSTANCE ID of the string
str = str + "Another value";
System.out.println(System.identityHashCode(str)); // Whoa, it's a different string!
的情況下,str變量指向是單獨不可變的,但是變量可以指向你想要字符串的任何實例。
如果你不希望它可以重新分配STR指向一個不同的字符串實例,聲明它最後:
final String str = "Test String";
System.out.println(System.identityHashCode(str)); // INSTANCE ID of the string
str = str + "Another value"; // BREAKS HORRIBLY
字符串是不變。
這意味着實例的String
不能更改。
您正在更改s
變量以引用不同的(但仍是不可變的)String
實例。
String s = new String();
創建一個新的不可變的空字符串變量「s」引用它。
s = s+"abc";
創建一個新的不可變的字符串;空字符串和「abc」,變量「s」的連接現在引用這個新對象。
一成不變的類是那些方法可以改變它們的字段,例如:
Foo f = new Foo("a");
f.setField("b"); // Now, you are changing the field of class Foo
但在不可變的類,例如字符串,創建後無法更改對象,但當然是,您可以將引用重新分配給另一個對象。例如:
String s = "Hello";
s.substring(0,1); // s is still "Hello"
s = s.substring(0,1); // s is now referring to another object whose value is "H"
只是爲了澄清,當你說s = s +「abc」; 這意味着,創建一個新的String實例(由s和「abc」組成),然後將該新的String實例分配給s。所以s中的新參考文獻與舊文獻有所不同。
請記住,變量實際上是對某個特定內存位置的對象的引用。即使您將變量更改爲在不同位置引用新對象,該位置的對象仍保留在該位置。
第一個答案是絕對正確的。您應該將其標記爲已回答。
s = s+"abc"
不附加到s對象。它會創建一個新的字符串,其中包含s對象(其中沒有)和「abc」中的字符。
如果字符串是可變的。它會有像在StringBuilder和StringBuffer上的append()和其他這樣的變異方法。
Josh Bloch的有效Java對不可變對象及其價值進行了很好的討論。
String s = new String();
空String
對象(""
)創建。變量s
引用該對象。
s = s + "abc";
是一個字符串(其只不過是一個String
對象,這是隱式地創建並保持在字符串的池),使得它可以再利用(因爲字符串是不可變的,因此是恆定的)。但是當你做new String()
是完全不同的,因爲你明確地創建對象,所以不會在池中結束。你可以通過一些被稱爲實習的東西扔在游泳池裏。
所以,s + "abc"
因爲在這一點上級聯和空字符串(""
)和並沒有真正創建一個新的String
對象,因爲最終的結果是這已經是在游泳池。因此,最後變量s
將引用池中的文字。
我相信你們都做得比所需要的要複雜得多,而這隻會讓那些試圖學習的人感到困惑!
製造物體中的Java不可變的主要好處是,它可以通過引用傳遞(例如另一種方法或使用賦值運算符分配),而不必擔心下游改變到對象中導致問題當前的方法或上下文。 (這比大約一個對象的線程安全任何對話非常不同。)
爲了說明,創建傳遞一個字符串作爲參數傳遞給一個單獨的方法的應用程序,並修改該方法中的字符串。在被調用方法的末尾打印字符串,然後控制權返回到調用方法。字符串會有不同的值,這是因爲它們指向不同的內存位置,這是「更改」不可變String的直接結果(創建一個新指針並將其指向後面的新值)。然後創建一個應用程序,除了使用StringBuffer之外,這些應用程序的功能是不可變的。 (例如,您可以追加到StringBuffer中進行修改。)打印的StringBuffers將具有相同的值,這是因爲它是(a)通過引用傳遞的,因爲Java會將所有傳遞給方法的對象作爲參數傳遞給(b)可變的。
我希望這可以幫助那些正在閱讀本主題並嘗試學習的人!
- 1. 混亂的字符串不變性
- 2. Java的字符串「常量」混亂
- 3. 混亂字符串 - Java方法
- 4. 字符串修改混亂在PHP
- 5. 混亂可變參數和字符串數組
- 6. 改變字符串的Java
- 7. 的Java字符/ INT轉換混亂
- 8. Java編碼有關字符串ARGS []和字串[] args混亂
- 9. 可變性混亂
- 10. 在混亂的字符串中查找字符串
- 11. java的混亂
- 12. Java字符串是不可變的嗎?
- 13. 在Java中不可變的字符串?
- 14. Python中的字符串不可改變
- 15. 一個關於Java字符串文字池中,並串的串聯混亂
- 16. 字符串池對象創建混亂
- 17. 字符串#分割方法混亂
- 18. JSON字符串編碼 - 混亂
- 19. 客觀C字符串混亂
- 20. 當從字符串轉換爲VB.net中的字符串時,字符串的內容變得混亂
- 21. Python模塊可變混亂
- 22. Java:如何「改變」一個字符串,儘管字符串的不變性?
- 23. PreparedStatement改變java中的字符串?
- 24. 在搜索字符串在C#中的列表一個混亂的字符串
- 25. 字符串不能更改。但int,字符可以改變
- 26. 字符編碼混亂!
- 27. 的jQuery /阿賈克斯可變混亂
- 28. 字符串轉換爲可變的Java
- 29. Java中的可變字符串
- 30. Java字符串混淆
因爲's'不是'final'。 – SLaks
s不是字符串,它是一個包含對字符串引用的容器。首先,它保存對新String()返回的字符串的引用,然後將其更改爲保存由新String()+「abc」返回的字符串的引用,即另一個字符串的引用。 – ignis