2012-01-19 39 views
5

Nếu String s là không thay đổi trong Java, thì làm sao chúng ta có thể viết như sau:Java chuỗi bất biến nhầm lẫn

String s = new String(); 
s = s + "abc"; 
+2

Vì 's' không phải là' final'. – SLaks

+1

s không phải là chuỗi, đó là vùng chứa chứa tham chiếu đến chuỗi. Đầu tiên, nó giữ tham chiếu đến chuỗi được trả về bởi String mới(), sau đó nó được thay đổi để giữ tham chiếu của chuỗi được trả về bởi chuỗi mới() + "abc" tức là tham chiếu của chuỗi khác. – ignis

Trả lời

7

Biến chuỗi của bạn KHÔNG phải là chuỗi. Đó là một REFERENCE cho một thể hiện của String.

Xem cho chính mình:

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! 

Các trường hợp biến điểm str đến là cá nhân không thay đổi, NHƯNG biến có thể được chỉ ra bất kỳ trường hợp của chuỗi bạn muốn.

Nếu bạn không muốn nó có thể gán str để trỏ đến một trường hợp chuỗi khác nhau, tuyên bố nó thức:

final String str = "Test String"; 
System.out.println(System.identityHashCode(str)); // INSTANCE ID of the string 

str = str + "Another value"; // BREAKS HORRIBLY 
+0

Điểm đúc 'String' thành 'Object' là gì? – Natix

+0

Đơn giản. str.toString() trả về ... chuỗi. Gọi ((Object) str) .toString() cho chúng ta ID cá thể thực tế. Điều này là dành cho mục đích trình diễn. –

+2

Không, không. Các phương thức trong Java là ảo, việc đưa một đối tượng vào một kiểu siêu không có tác dụng ở đây. Việc thực hiện phương thức 'toString()' của 'String' sẽ được gọi lại. Bạn cần phải gọi 'System.identityHashCode (str)' để lấy mã băm mã nhận diện gốc của một đối tượng. – Natix

8

Strings không thay đổi.
Điều đó có nghĩa là một ví dụ của String không thể thay đổi.

Bạn đang thay đổi sbiến để tham chiếu đến một trường hợp khác (nhưng vẫn không thay đổi) String.

0
String s = new String(); 

Tạo chuỗi mới, không thay đổi, trống, biến "s" tham chiếu nó.

s = s+"abc";    

Tạo chuỗi mới, không thay đổi được; kết nối chuỗi rỗng và "abc", biến "s" hiện tham chiếu đối tượng mới này.

1

Lớp học bất biến là những người có phương pháp có thể thay đổi lĩnh vực của họ, ví dụ:

Foo f = new Foo("a"); 
f.setField("b"); // Now, you are changing the field of class Foo 

nhưng trong lớp học bất biến, ví dụ Chuỗi, bạn không thể thay đổi đối tượng khi tạo, nhưng tất nhiên là, bạn có thể gán lại tham chiếu cho một đối tượng khác. Ví dụ:

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" 
0

Chỉ cần làm rõ, khi bạn nói s = s + "abc"; Điều đó có nghĩa là, tạo một thể hiện String mới (bao gồm s và "abc") sau đó gán thể hiện String mới cho s. Vì vậy, tham chiếu mới trong s khác với cũ.

Hãy nhớ rằng, biến có hiệu quả là tham chiếu đến một đối tượng tại một số vị trí bộ nhớ cụ thể. Đối tượng tại vị trí đó vẫn ở vị trí đó, ngay cả khi bạn thay đổi biến để chỉ một đối tượng mới tại một vị trí khác.

2

Câu trả lời đầu tiên là hoàn toàn chính xác. Bạn nên đánh dấu nó là đã trả lời.

s = s+"abc" không thêm vào đối tượng. nó tạo ra một chuỗi mới chứa các ký tự từ đối tượng s (trong đó không có ký tự nào) và "abc".

nếu chuỗi có thể thay đổi được. nó sẽ có các phương thức như append() và các phương thức đột biến khác trên StringBuilder và StringBuffer.

Java hiệu quả bởi Josh Bloch có thảo luận tuyệt vời về các đối tượng bất biến và giá trị của chúng.

0
String s = new String(); 

Một String đối tượng rỗng ("") được tạo ra. Và biến số s đề cập đến đối tượng đó.

s = s + "abc"; 

"abc" là một chuỗi chữ (đó là gì, nhưng một đối tượng String, được ngầm tạo ra và giữ trong một vũng chuỗi) để nó có thể được tái sử dụng (vì dây là không thay đổi và do đó là không đổi). Nhưng khi bạn làm new String() là hoàn toàn khác nhau bởi vì bạn đang rõ ràng tạo đối tượng để không kết thúc trong hồ bơi. Bạn có thể ném vào hồ bơi bằng một cái gì đó gọi là interning.

Vì vậy, s + "abc" kể từ thời điểm này nối và chuỗi rỗng ("") và "abc" không thực sự tạo ra một đối tượng mới String vì kết quả cuối cùng là "abc" đó là đã có trong hồ bơi. Vì vậy, cuối cùng biến số s sẽ tham chiếu đến chữ số "abc" trong hồ bơi.

-2

Tôi tin rằng tất cả các bạn đang làm cho điều này phức tạp hơn nhiều so với nhu cầu cần thiết, và điều đó chỉ đơn giản là làm xáo trộn những người đang cố gắng học! Lợi ích chính của việc tạo một đối tượng bất biến trong Java là nó có thể được truyền bằng tham chiếu (ví dụ như phương pháp khác hoặc được gán bằng toán tử gán) mà không cần phải lo lắng về việc thay đổi về phía đối tượng phương thức hoặc ngữ cảnh hiện tại. (Điều này rất khác so với bất kỳ cuộc trò chuyện nào về sự an toàn của một đối tượng.)

Để minh họa, hãy tạo một ứng dụng chuyển một String thành tham số cho một phương thức riêng biệt và sửa đổi Chuỗi trong phương thức đó. In chuỗi ở cuối phương thức được gọi và sau đó sau khi điều khiển trả về phương thức gọi. Các chuỗi sẽ có các giá trị khác nhau, và đó là vì chúng trỏ đến các vị trí bộ nhớ khác nhau, kết quả trực tiếp của việc "thay đổi" chuỗi bất biến (tạo một con trỏ mới và trỏ nó đến một giá trị mới đằng sau hậu trường). Sau đó, tạo một ứng dụng thực hiện những điều tương tự ngoại trừ với StringBuffer, mà không phải là bất biến. (Ví dụ, bạn có thể thêm vào StringBuffer để sửa đổi nó.) StringBuffer đã in sẽ có cùng giá trị, và đó là bởi vì nó (a) được truyền theo tham chiếu, như Java thực hiện với tất cả các đối tượng được truyền cho các phương thức như tham số và (b) có thể thay đổi.

Tôi hy vọng điều này sẽ giúp mọi người đang đọc chủ đề này và cố gắng tìm hiểu!