Phương thức toString()
, nhà điều hành ==
và phương thức equals()
hoạt động khác hoặc tương tự như thế nào trên các loại tham chiếu và nguyên thủy?Các phương thức đối tượng toString(), ==, equals() hoạt động khác nhau hoặc tương tự như thế nào trên các kiểu tham chiếu và nguyên thủy?
Trả lời
Đối với các loại tham chiếu, == sẽ so sánh tham chiếu thực tế (trong bộ nhớ trong đối tượng cư trú) ở đâu khi phương thức bằng thực hiện so sánh dữ liệu.
Đôi khi JVM "Chuỗi thực tập" các chuỗi không thay đổi của bạn vì lý do hiệu suất. Gây ra điều này:
String a = "abc";
String b = "abc";
if (a == b){
//The if statement will evaluate to true,
//if your JVM string interns a and b,
//otherwise, it evaluates to false.
}
Các '==' điều hành hoạt động trên các loại nguyên thủy mà bạn có, mà trong trường hợp của các đối tượng tham chiếu là tài liệu tham khảo chính nó. Đó là a == b
sẽ so sánh các giá trị cho các kiểu nguyên thủy dưới dạng int, nhưng sẽ so sánh tham chiếu (không phải giá trị) cho các loại tham chiếu. Hai đối tượng của loại tham chiếu không giống nhau nhưng có cùng giá trị sẽ trả về true
khi phương thức equals()
được gọi, nhưng a == b
sẽ là sai.
Đối với các kiểu nguyên thủy, khi gọi phương thức, loại trước đó được chuyển đổi (đóng hộp) thành kiểu tham chiếu và sau đó phương thức được gọi. Điều này có nghĩa là đối với các kiểu nguyên thủy a == b
sẽ mang lại giá trị giống như a.equals(b)
, nhưng trong trường hợp sau hai đối tượng đóng hộp tạm thời được tạo trước khi gọi phương thức equals()
. Điều này sẽ làm cho các hoạt động tốn kém hơn trong thời gian CPU mà có thể hoặc có thể không phải là một vấn đề tùy thuộc vào nơi nó xảy ra.
Tức là, để so sánh giá trị kiểu gốc bạn nên sử dụng ==
, trong khi để so sánh giá trị loại tham chiếu, bạn nên sử dụng phương pháp .equals()
.
Điều tương tự cũng xảy ra với phương thức toString()
. Khi được gọi trên một đối tượng kiểu tham chiếu, nó sẽ gọi phương thức thích hợp và tạo ra một String. Khi được gọi trên kiểu nguyên thủy, kiểu sẽ được tự động đóng hộp và sau đó phương thức sẽ được gọi trong đối tượng tạm thời. Trong trường hợp này, bạn có thể gọi phương thức tĩnh toString()
thích hợp (ví dụ: đối với int call Integer.toString(myint)
) điều này sẽ tránh tạo đối tượng tạm thời.
'a.equals (b)' sẽ không biên dịch nếu 'a' là kiểu nguyên thủy. – ajb
Đối với các loại thông thường (bao gồm String):
==
so sánh tham chiếu đối tượng. Nó kiểm tra nếu hai tham chiếu đối tượng là như nhau; tức là nếu họ đề cập đến cùng một đối tượng.equals(Object)
kiểm tra xem đối tượng này có "bằng với" đối tượng khác không. Điều gì "bằng" có nghĩa là phụ thuộc vào cách lớp của đối tượng định nghĩa sự bình đẳng. Lớpjava.lang.Object
định nghĩaequals(other)
làthis == other
, nhưng nhiều lớp ghi đè định nghĩa này.toString()
cung cấp chuyển đổi đơn giản đối tượng thành Chuỗi. Các định dạng và nội dung của chuỗi kết quả là lớp cụ thể, và (từ quan điểm của hợp đồngjava.lang.Object
) không có đảm bảo rằng nó sẽ có ý nghĩa.
Đối với (true) loại nguyên thủy:
==
so sánh giá trị của các loại, vàequals()
vàtoString()
không được định nghĩa. Java không cho phép bạn gọi một phương thức trên một giá trị nguyên thủy.
Tuy nhiên điều này là rất phức tạp bởi thực tế là trong một số bối cảnh ngôn ngữ Java nói rằng một loại nguyên thủy có thể được "autoboxed" để cung cấp cho một thể hiện của loại wrapper tương ứng kiểu nguyên thủy của; ví dụ. int
tương ứng với java.lang.Integer
, v.v. Đối với các lớp wrapper:
==
được định nghĩa tương tự như đối với bất kỳ loại tài liệu tham khảo khác,equals()
so sánh giá trị gói, vàtoString()
định dạng các giá trị gói.
Các cờ lê trong các công trình được minh họa bằng những điều sau đây:
int a = ...
int b = a;
Integer aa = a; // autoboxing occurs
Integer bb = b; // autoboxing occurs
assert a == b; // always succeeds
assert aa.equals(bb); // always succeeds
assert aa == bb; // sometimes succeeds, sometimes fails.
Lý do mà cuối cùng đôi khi thất bại là JLS không đảm bảo rằng autoboxing một giá trị nguyên thủy nhất định sẽ luôn luôn cung cấp cho các wrapper cùng vật. Nó sẽ trong một số trường hợp (ví dụ: đối với các số nguyên nhỏ) và sẽ không dành cho người khác (ví dụ: số nguyên lớn).
Bài học được học từ ví dụ trên là bạn cần phải rất cẩn thận khi sử dụng ==
trên loại tham chiếu. Chỉ sử dụng nó khi bạn thực sự muốn kiểm tra xem hai tham chiếu có đến cùng một đối tượng hay không. Không sử dụng nó nếu bạn chỉ muốn kiểm tra nếu các đối tượng là "bình đẳng" mà không có chi phí gọi equals()
.
(Cũng lưu ý rằng String
là một loại nơi ==
sẽ cung cấp cho bạn câu trả lời sai trong nhiều tình huống, xem How do I compare strings in Java?.)
'==' trên nguyên thủy chỉ kiểm tra các giá trị và bỏ qua các loại. 'int x = 5; dài y = 5L; byte b = 5; x == y; b == x; 'Cả hai đều trả về true. – arun
Nó không phải là "bỏ qua" các loại. Một hoặc các toán hạng khác đang được thăng cấp thành loại khác. Bên cạnh đó, tôi đã nói "giá trị của loại" ... –
- 1. Phương thức equals có hoạt động với các đối tượng không? Nếu vậy, làm thế nào?
- 2. Cách gửi đa phương thức trên các kiểu nguyên thủy?
- 3. Phương thức .ToString() hoạt động như thế nào?
- 4. ToString có được gọi cho các kiểu nguyên thủy không?
- 5. Sự khác biệt giữa các loại nguyên thủy và tham chiếu là gì?
- 6. Tại sao phương thức toString() hoạt động khác nhau giữa mảng và đối tượng ArrayList trong Java
- 7. Các biểu thức lambda hoạt động như thế nào?
- 8. Android: Không thể gọi toString() trên kiểu nguyên thủy int
- 9. Các enums Java có được coi là các kiểu nguyên thủy hay tham chiếu không?
- 10. Tạo các bài kiểm tra đơn vị cho các phương thức hashcode, equals và toString
- 11. Các kiểu cấu trúc và nguyên thủy
- 12. Sự khác nhau giữa các tham chiếu và các đối tượng trong java là gì?
- 13. Số nguyên là kiểu nguyên thủy
- 14. Các tham chiếu đối tượng khác nhau cho cùng một đối tượng (?)
- 15. Tham chiếu đối tượng vs kiểu trả về Void cho phương thức
- 16. Việc sử dụng tham chiếu const đi tới các kiểu nguyên thủy là gì?
- 17. Sự khác nhau giữa toán tử == và phương thức Equals() trong C#?
- 18. Sử dụng các kiểu nguyên thủy với ClassLoader
- 19. Phương thức equals của Scala hoạt động như thế nào trong trường hợp của Danh sách?
- 20. Phương thức phản đối này hoạt động như thế nào?
- 21. Cách phân biệt tham chiếu so với kiểu nguyên thủy và giá trị
- 22. Kiểu nguyên thủy vs Kiểu đối tượng trong Java
- 23. Pthread_key_t và phương thức pthread_key_create hoạt động như thế nào?
- 24. Sự khác nhau giữa .Equals và ==
- 25. Java làm thế nào để gọi phương thức bằng cách phản chiếu với các loại nguyên thủy như các đối số
- 26. ActionScript - Sự khác biệt giữa các đối tượng nguyên thủy/không nguyên thủy để quản lý bộ nhớ?
- 27. Vectơ tham chiếu đến các đối tượng
- 28. Các hoạt động của FP có cho kết quả tương tự trên các CPU x86 khác nhau không?
- 29. Linq2Sql: HasValue và! = Null, có hoạt động tương tự đối với các kiểu nullable không?
- 30. Các tham chiếu yếu được triển khai như thế nào?
học một khái niệm mới - thực tập! – lft93ryt