Java sẽ hằng tập string (chuỗi thức) và literals (tạo một thể hiện của mỗi chuỗi trong một hồ bơi nội bộ) và do đó bạn có thể nhận được cùng một ví dụ, ngay cả nếu nó được "tạo ra" bằng cách nối.
Và như những người khác đã nêu, tối ưu hóa trình biên dịch sẽ thực sự chuyển nối thành một chữ ("ab").
Bạn không bao giờ có thể hoàn toàn dựa vào ngữ nghĩa của chuỗi ==
của chuỗi, đó là lý do tại sao bạn nên luôn sử dụng equals(..)
.
Edit: để làm rõ các câu trên:
Với đối tượng ==
luôn có nghĩa là tài liệu tham khảo được so sánh và nó sẽ luôn luôn trả về true nếu cả hai tài liệu tham khảo đều giống nhau. Tuy nhiên, bạn không thể luôn luôn dựa vào việc tham chiếu cùng một đối tượng (như trong ví dụ của bạn, nơi đơn giản là final
hành vi thay đổi hoặc trong các khung như Hibernate, v.v.) - đó là lý do tại sao bạn nên sử dụng equals(...)
để thay thế.
Tất nhiên bạn có thể sử dụng ==
nếu bạn cần bình đẳng vật lý (cùng một đối tượng) thay vì bình đẳng logic (cùng một giá trị).
Một ví dụ khác nơi ==
sẽ có kết quả khác nhau, mặc dù từ một điểm locical nhìn cả hai nên được đúng:
Integer l1 = 0;
Integer l2 = 0;
l1 == l2; //most often true, since Integer objects up to 127 are cached
Integer l1 = 1000;
Integer l2 = 1000;
l1 == l2; //most often false, since those are not cached anymore
Lưu ý rằng với "thường xuyên nhất" Tôi có nghĩa là điều này có thể thay đổi giữa các phiên bản Java (nếu không phải các JVM khác nhau), mặc dù điều đó không có khả năng xảy ra.
... là một nửa câu trả lời ... ;-) –