2012-09-09 37 views
7

tôi chạy chương trình sau đây,Java String vấn đề

String firstString = "String"; 
    String secondString = "String"; 
    String thirdString = new String("String"); 
    System.out.println(firstString == secondString); 
    System.out.println(firstString == thirdString); 
    System.out.println(firstString.intern() == thirdString); 
    System.out.println(firstString.intern() == thirdString.intern()); 
    System.out.println(firstString.intern().equals(thirdString.intern())); 
    System.out.println(firstString == thirdString); 

và đầu ra của tôi là

true 
false 
false 
true 
true 
false 

Tôi đã học được rằng hồ JVM chuỗi với cùng một nội dung như cùng một chuỗi. Có đúng không? Nếu đó là sự thật thì tại sao không phải là firstString == thirdString trả về false? Có jvm chỉ bơi chuỗi chỉ được khởi tạo với: "" và không phải với toán tử mới?

+0

Hãy thử thêm: 'firstString == thirdString.intern()', để thấy rằng các chuỗi ký tự chuỗi được tự động nội bộ hóa. –

Trả lời

6

Việc gộp nhóm chỉ liên quan đến chuỗi ký tự - vì vậy firstStringsecondString thực sự là cùng một đối tượng - trong đó như trong thirdString bạn đã yêu cầu một đối tượng mới được tạo trên heap một cách rõ ràng.

Tôi khuyên bạn nên đọc phần về string literals in the spec.

Nó cung cấp thêm thông tin về cách thức và thời điểm chuỗi được gộp chung.

Ngoài ra, hãy lưu ý đến những viên đạn ở phần cuối của bộ phận:

  • chuỗi Literal trong cùng một lớp (§8) trong cùng một gói (§7) đại diện tham chiếu đến cùng một chuỗi đối tượng (§4.3.1).
  • Chuỗi ký tự trong các lớp khác nhau trong cùng một gói đại diện cho tham chiếu đến cùng một đối tượng Chuỗi.
  • Chuỗi ký tự trong các lớp khác nhau trong các gói khác nhau tương tự như vậy đại diện cho các tham chiếu đến cùng một đối tượng String.
  • Các chuỗi được tính theo biểu thức hằng số (§15.28) được tính tại thời gian biên dịch và sau đó được xử lý như thể chúng là các chữ.
  • Chuỗi được tính bằng cách nối vào thời gian chạy mới được tạo và do đó khác biệt.
+0

OK Tôi đồng ý với các giải thích của bạn. Tôi đã tạo một đối tượng mới như là thirdObject với "String" trong heap. Tôi đã thực tập nó. Vì vậy, trong hồ bơi sẽ có hai đối tượng phải không? Chuỗi đầu tiên và secong sẽ tham chiếu đến đối tượng A (để trích dẫn) và chuỗi thứ ba sẽ chỉ một đối tượng khác (B). – vvekselva

0

thirdString KHÔNG phải là từ nhóm. Nó không phải là một chuỗi chữ, bạn tự động tạo nó với toán tử new.

secondString mặt khác - được lấy từ hồ bơi (bạn gán một chuỗi ký tự cho nó), vì vậy cùng một đối tượng được gán cho cả hai firstStringsecondString.

-1

"firstString == thirdString" trả về false.

Thực tập phương thức "trả về biểu diễn chính tắc cho đối tượng chuỗi". Nếu bạn gán chuỗi thực tập nội trú:

thirdString=thirdString.intern(); 

cuối cùng "firstString == thirdString" trả về true

2

Đối firstString và secondString, JVM sẽ tra cứu hồ bơi chuỗi và trả lại tài liệu tham khảo của "String".

Đối với ThirdString, JVM sẽ không tra cứu nhóm chuỗi và sẽ chỉ tạo đối tượng String trong heap.

Đối với OneString.intern(), JVM sẽ tìm kiếm tham chiếu trong chuỗi chuỗi, thêm OneString vào chuỗi nhóm nếu OneString không tồn tại trong đó và trả về tham chiếu.

+0

Tôi có một truy vấn, thêm đối tượng (chuỗi) trong nhóm dựa trên hàm băm đối tượng hoặc nội dung đối tượng (biểu diễn chuẩn). Gọi thực tập sẽ thêm vào hồ bơi và trả về biểu diễn kinh điển có nghĩa là tất cả các chuỗi nên tham chiếu đến cùng một vì tất cả đều có cùng một biểu diễn kinh điển. – vvekselva

+0

Sau khi gọi hàm intern(), chuỗi sẽ được thêm vào nhóm chuỗi và đối tượng String sẽ tham chiếu đến tham chiếu chuỗi mới trong chuỗi chuỗi. Đối tượng chuỗi ban đầu sẽ được GC thu thập lần sau. –

+0

Có cách nào để lập hồ sơ này không? Tôi chỉ muốn kiểm tra nội dung của hồ bơi thực tập? có cách nào không? – vvekselva