2010-03-23 41 views
10
Integer i = 127; 
Integer j = 127; 
System.out.println(i == j); 
System.out.println(i.equals(j)); 

Integer i1 = 128; 
Integer j1 = 128; 
System.out.println(i1 == j1); 
System.out.println(i1.equals(j1)); 

Tôi không hiểu tại sao nó không in "true, true, true, true". xin vui lòng cho câu trả lời?Mã sau đây in "true, true, false, true". Không nên là "đúng, đúng, đúng, đúng"?

+2

như vậy một câu hỏi cụ thể, hmm, đáng ngờ – Will

+1

@ Will Tôi đã nhìn thấy cùng một câu hỏi trong một cuốn sách SCJP –

+1

tôi đặt cược rằng nó trả về false, true, false, true thay vì true, true, false, true –

Trả lời

29

Khi bạn sử dụng ==, bạn đang so sánh các trường hợp đối tượng đối tượng để bình đẳng.

Lý do mà hai trường hợp đầu tiên đều bình đẳng là bạn tạo ra bằng cách sử dụng Integers autoboxing (thay vì gọi new Integer(127)), và Java Language Specification §5.1.7 đòi hỏi Integers giữa -128 và 127 được lưu trữ.

Triển khai có thể cache nhiều giá trị hơn nhưng không bắt buộc; dường như JVM bạn đang sử dụng không cache 128. Đây là trường hợp của Sun Java 6.

5

Số nguyên là một lớp. Nếu bạn gõ Integer mới() bạn tạo một đối tượng mới. Vì vậy, i, j, i1 và j1 là tất cả các đối tượng khác nhau. Nếu bạn sử dụng == nó chỉ đúng trên cùng một đối tượng. Đối với các số nguyên nhỏ hơn 128, JVM luôn sử dụng cùng một đối tượng để kết quả đầu ra đúng.

4

Không nó không nên:

Integer i1 = 128; 
Integer j1 = 128; 

autoboxing gây hai đối tượng Integer khác biệt được tạo ra trong việc thực hiện Java mà bạn đang sử dụng.

Nếu các giá trị số nguyên nằm trong khoảng từ -128 đến 127, thì JLS quy định rằng đối tượng Integer giống nhau sẽ được sử dụng; xem JLS 1.5.7. Tuy nhiên, JLS thực hiện không phải yêu cầu rằng i1i2 phải có các giá trị khác ngoài phạm vi đó. Thật vậy, các cuộc thảo luận sau đây trong JLS cho biết điều này:

Lý tưởng nhất, hãy bỏ một giá trị nguyên thủy p, sẽ luôn mang lại một tham chiếu giống nhau. Trong thực tế, điều này có thể không khả thi khi sử dụng các kỹ thuật triển khai hiện có. Các quy tắc trên là một sự thỏa hiệp thực dụng. Điều khoản cuối cùng ở trên yêu cầu các giá trị chung nhất định luôn được đóng hộp thành các đối tượng không thể phân biệt được. Việc triển khai có thể lưu vào bộ nhớ cache, lười biếng hoặc háo hức.

Đối với các giá trị khác, công thức này không cho phép bất kỳ giả định nào về danh tính của các giá trị được đóng hộp trên phần của lập trình viên. Điều này sẽ cho phép (nhưng không yêu cầu) chia sẻ một số hoặc tất cả các tài liệu tham khảo này.

Điều này đảm bảo rằng trong hầu hết các trường hợp phổ biến, hành vi sẽ là hành vi mong muốn, không áp đặt hình phạt hiệu suất quá mức, đặc biệt là trên các thiết bị nhỏ. Ví dụ, ít triển khai bộ nhớ hạn chế hơn, có thể lưu tất cả các ký tự và quần short, cũng như các số nguyên và độ dài trong phạm vi -32K - + 32K.

+0

Bạn đánh vần 2 bằng tiếng Anh như thế nào? –

+0

@PP - nó phải sau giờ đi ngủ của bạn :-) –

+0

Nếu tôi nhớ chính xác, Sun Java 7 sẽ có bộ đệm ẩn Integer có thể cấu hình. Tôi nghĩ rằng nó đặc biệt giúp cho một số điểm chuẩn. –

9

chỉ để thêm vào tất cả các câu trả lời đúng khác, hãy nhìn vào các source code để hiểu đầy đủ những gì @mmyers đang nói:

584  /** 
    585  * Returns an {@code Integer} instance representing the specified 
    586  * {@code int} value. If a new {@code Integer} instance is not 
    587  * required, this method should generally be used in preference to 
    588  * the constructor {@link #Integer(int)}, as this method is likely 
    589  * to yield significantly better space and time performance by 
    590  * caching frequently requested values. 
    591  * 
    592  * @param i an {@code int} value. 
    593  * @return an {@code Integer} instance representing {@code i}. 
    594  * @since 1.5 
    595  */ 
    596  public static Integer valueOf(int i) { 
    597   final int offset = 128; 
    598   if (i >= -128 && i <= 127) { // must cache 
    599    return IntegerCache.cache[i + offset]; 
    600   } 
    601   return new Integer(i); 
    602  } 
+2

Bạn cũng phải biết rằng 'Integer i = x' được biên dịch thành' Integer.valueOf (x) 'nội bộ, nó là gì. –

+0

Cảm ơn, cảm thấy một cái gì đó đã mất tích. – Tom

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