2009-10-18 21 views

Trả lời

2

Đố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. 
} 

http://en.wikipedia.org/wiki/String_interning

+0

học một khái niệm mới - thực tập! – lft93ryt

1

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.

+0

'a.equals (b)' sẽ không biên dịch nếu 'a' là kiểu nguyên thủy. – ajb

7

Đố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ớp java.lang.Object định nghĩa equals(other)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 đồng java.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()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?.)

+0

'==' 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

+1

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" ... –

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