TL; DR
Java lưu vào bộ đệm ẩn các phiên bản Integer từ -128
đến 127
. Vì bạn đang sử dụng ==
để so sánh các tham chiếu đối tượng thay vì giá trị , nên chỉ các đối tượng được lưu trong bộ nhớ cache mới khớp. Làm việc với long
các giá trị nguyên thủy không được đóng hộp hoặc sử dụng .equals()
để so sánh các Long
đối tượng của bạn .
Phiên bản dài (dự định chơi chữ)
Tại sao có vấn đề khi so sánh biến Long với giá trị lớn hơn 127? Nếu kiểu dữ liệu của biến trên là nguyên thủy (dài) thì mã sẽ hoạt động với tất cả các giá trị.
Java lưu vào bộ nhớ cache các cá thể của đối tượng Số nguyên từ phạm vi -128 đến 127 . Mà nói:
- Nếu bạn đặt giá trị là N biến Long
127
(được lưu trong bộ nhớ cache ), thì cùng một đối tượng sẽ được trỏ tới bởi tất cả các tham chiếu. (N biến, 1 trường hợp)
- Nếu bạn đặt giá trị là N Biến dài
128
( không được lưu trong bộ nhớ cache ), bạn sẽ có một cá thể đối tượng được trỏ bởi mọi tham chiếu. (N biến, N phiên bản)
Đó là lý do tại sao điều này:
Long val1 = 127L;
Long val2 = 127L;
System.out.println(val1 == val2);
Long val3 = 128L;
Long val4 = 128L;
System.out.println(val3 == val4);
Kết quả này:
đúng
sai
Đối với giá trị 127L , vì cả hai tham chiếu (val1 và val2) đều trỏ đến cùng một thể hiện đối tượng trong bộ nhớ (được lưu trong bộ nhớ đệm), nó sẽ trả về true
.
Mặt khác, đối với giá trị 128 , vì không có phiên bản nào cho nó được lưu trong bộ nhớ, một phiên bản mới được tạo cho bất kỳ phép gán mới nào cho các giá trị được đóng hộp, dẫn đến hai phiên bản khác nhau (được trỏ bởi val3 và val4) và trả false
về so sánh giữa chúng.
Điều đó chỉ xảy ra bởi vì bạn đang so sánh hai Long
tham chiếu đối tượng , không phải long
giá trị nguyên thủy, với ==
toán tử. Nếu không có cơ chế Cache này, các phép so sánh này sẽ luôn thất bại, vì vậy vấn đề thực sự ở đây là so sánh các giá trị được đóng hộp với ==
toán tử.
Việc thay đổi các biến này thành kiểu nguyên thủy long
sẽ ngăn điều này xảy ra, nhưng trong trường hợp bạn cần giữ mã của mình bằng cách sử dụng Long
các đối tượng, bạn có thể thực hiện các so sánh này một cách an toàn với các cách tiếp cận sau:
System.out.println(val3.equals(val4)); // true
System.out.println(val3.longValue() == val4.longValue()); // true
System.out.println((long)val3 == (long)val4); // true
(Kiểm tra rỗng thích hợp là cần thiết, ngay cả đối với vật đúc)
IMO , luôn là một ý kiến hay khi sử dụng các phương thức .equals () khi xử lý các phép so sánh Đối tượng.
Các liên kết tham khảo:
.longValue()
.