2013-05-19 30 views
5

Tôi đã tìm thấy một trường hợp thú vị trong khi thử nghiệm bằng tạo chuỗi và kiểm tra mã băm của chúng.Thử nghiệm với việc tạo chuỗi

Trong trường hợp đầu tiên tôi tạo ra chuỗi sử dụng bản sao constructor:

public class Test { 

    /** 
    * @param args 
    */ 
    public static void main(String[] args) { 

     String s1 = new String("myTestString"); 

     String s3 = s1.intern(); 

     System.out.println("S1: " + System.identityHashCode(s1) + " S3:" 
       + System.identityHashCode(s3)); 
    } 


} 

Output mã trên là:

S1: 816.115.710 S3: 478684581

này dự kiến ​​sản lượng như chuỗi tập trung chọn tham chiếu từ nhóm Chuỗi trong khi s1 chọn tham chiếu của đối tượng mới. Vì vậy, mã băm nhận dạng của chúng khác nhau.

Bây giờ nếu tôi tạo ra chuỗi sử dụng mảng char sau đó tôi nhìn thấy một số hành vi kỳ lạ:

public class Test { 

    /** 
    * @param args 
    */ 
    public static void main(String[] args) { 

     char[] c1 = { 'm', 'y', 'T', 'e', 's', 't', 'S', 't', 'r', 'i', 'n', 
       'g' }; 

     String s5 = new String(c1); 

     String s6 = s5.intern(); 

     System.out.println("S5: " + System.identityHashCode(s5) + " S6:" 
       + System.identityHashCode(s6)); 
    } 

} 

Output mã trên là:

S5: 816.115.710 S6: 816115710

Đây là một đầu ra không mong muốn. Làm thế nào có thể tập trung String và đối tượng String mới có cùng một identityhashcode ??

Bất kỳ ý tưởng nào?

+0

Hãy xem http://stackoverflow.com/questions/1063068/how -does-the-jvm-đảm bảo-rằng-system-identityhashcode-sẽ-không bao giờ thay đổi –

+0

@IgorS .: Làm thế nào nó được liên kết với câu hỏi của tôi? – Lokesh

+1

"Nhiều đối tượng có thể có cùng mã băm nhận dạng. Đó là bản chất của mã băm". –

Trả lời

3

Trong trường hợp đầu tiên, myTestString đen là trên hồ bơi trước bạn gọi intern, trong khi ở trường hợp thứ hai nó không phải là quá Chuỗi bạn s5 được đặt trong hồ bơi trực tiếp.

Nếu chúng ta đi qua ví dụ của bạn từng bước, đây là những gì sẽ xảy ra:

  • String s1 = new String("myTestString"); => việc sử dụng một chuỗi đen tạo ra một String myTestString trong hồ bơi (chúng ta hãy gọi nó s0), và một Chuỗi mới s1 cũng được tạo, không có trong hồ bơi.
  • String s3 = s1.intern(); => kiểm tra xem có một Chuỗi tương đương trong hồ bơi và tìm thấy s0 hay không. Bây giờ s3s0 tham chiếu đến cùng một trường hợp (ví dụ: s3 == s0 là đúng, nhưng s1 != s0).

Trong ví dụ thứ hai của bạn:

  • String s5 = new String(c1); tạo một String mới, mà không phải là trong hồ bơi
  • String s6 = s5.intern(); kiểm tra nếu myTestString là trong hồ bơi nhưng không thể tìm thấy nó, vì vậy cuộc gọi đến intern tạo một tham chiếu String mới trong nhóm tham chiếu đến cùng một Chuỗi là s5. Vì vậy, s6 == s5 là sự thật.

Cuối cùng bạn có thể chạy hai chương trình này để xác nhận giải thích của tôi (thứ hai một bản in true ba lần):

public static void main(String[] args) { 
    String s1 = new String("myTestString"); 
    String s3 = s1.intern(); 
    System.out.println("myTestString" == s1); 
    System.out.println(s3 == s1); 
    System.out.println("myTestString" == s3); 
} 

public static void main(String[] args) { 
    String s1 = new String(new char[] {'m', 'y', 'T', 'e', 's', 't', 'S', 't', 'r', 'i', 'n', 'g'}); 
    String s3 = s1.intern(); 
    System.out.println("myTestString" == s3); 
    System.out.println("myTestString" == s1); 
    System.out.println(s3 == s1); 
} 
+0

Tại sao s5 được đưa vào hồ bơi trực tiếp? Tôi đang sử dụng toán tử mới để tạo nó. – Lokesh

+0

Nó được đặt trong hồ bơi khi bạn gọi thực tập vì chuỗi cụ thể đó chưa có trong hồ bơi. Cách bạn tạo chuỗi không liên quan trong trường hợp đó. – assylias

+0

tương tự cũng nên áp dụng cho s1, s3 sau đó. Tại sao điều đó lại khác? – Lokesh

Các vấn đề liên quan