2009-10-18 16 views

Odpowiedz

2

Dla typów odniesienia, == porówna rzeczywiste odniesienie (gdzie w pamięci znajduje się obiekt), gdzie jako metoda równości przeprowadza porównanie danych.

JVM czasami będzie "strunowe" z niezmiennymi ciągami ze względu na wydajność. Powodując w ten sposób:

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

nauczył się nowej koncepcji - interning! – lft93ryt

1

do „==” podmiot działający na prymitywnym rodzaju masz, że w przypadku obiektów referencyjnych jest samo odniesienie. To jest a == b porówna wartości dla typów pierwotnych jako int, ale porówna odniesienie (nie wartość) dla typów odniesienia. Dwa obiekty typu odniesienia, które nie są takie same, ale mają tę samą wartość, zwrócą true po wywołaniu metody equals(), ale a == b będzie fałszywa.

W przypadku typów pierwotnych podczas wywoływania metody typ jest wcześniej konwertowany (w ramkach) na typ odniesienia, a następnie wywoływana jest metoda. Oznacza to, że dla typów pierwotnych a == b przyniesie tę samą wartość, co a.equals(b), ale w drugim przypadku zostaną utworzone dwa tymczasowe obiekty w ramkach przed wywołaniem metody equals(). To spowoduje, że operacja będzie droższa w czasie pracy procesora, co może, ale nie musi być problemem w zależności od tego, gdzie to się dzieje.

To znaczy, aby porównać prymitywne wartości typów, należy użyć ==, natomiast w celu porównania wartości typów odniesienia należy użyć metody .equals().

To samo dzieje się z metodą toString(). Po wywołaniu obiektu typu referencyjnego wywoła odpowiednią metodę i utworzy łańcuch. Gdy zostanie wywołany typ pierwotny, typ będzie autoboxed, a następnie metoda zostanie wywołana w tymczasowym obiekcie. W takim przypadku można wywołać odpowiednią metodę statyczną toString() (tj. Dla połączenia int Integer.toString(myint)), co pozwoli uniknąć tworzenia obiektu tymczasowego.

+0

'a.equals (b)' nie skompiluje się, jeśli 'a' jest typem pierwotnym. – ajb

7

Dla stałych typów (w tym String):

  • == porównuje referencje obiektów. Testuje, czy dwa odwołania do obiektów są równe; tj. jeśli odnoszą się do tego samego obiektu.
  • equals(Object) testuje, czy ten obiekt jest "równy" innemu. To, co "równa się" oznacza, zależy od tego, w jaki sposób klasa obiektu definiuje równość. Klasa java.lang.Object definiuje equals(other) jako this == other, ale wiele klas zastępuje tę definicję.
  • toString() zapewnia prostą konwersję obiektu na ciąg. Format i zawartość wynikowego ciągu znaków jest specyficzny dla klasy i (z punktu widzenia umowy java.lang.Object) nie ma gwarancji, że będzie ona znacząca.

(prawda) Do podstawowych typów:

  • == porównuje wartości typu i
  • equals() i toString() nie są określone. Java nie zezwala na wywoływanie metody na pierwotnej wartości.

Jednak to jest skomplikowana przez fakt, że w niektórych kontekstach języka Java mówi, że prymitywny typ może być „autoboxed” dać instancję odpowiedniego rodzaju otoki prymitywnego TYP za; na przykład int odpowiada java.lang.Integer i tak dalej. Dla klas bibułki:

  • == są określone tak samo jak w przypadku wszystkich innych typów odniesienia
  • equals() porównuje owinięte wartości,
  • toString() formatuje owinięte wartości.

klucza w pracach ilustruje następujący:

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. 

tego powodu, że ostatni czasami nie jest to, że JLS nie gwarantuje, że autoboxing daną wartość prymitywny zawsze daje ten sam opakowanie obiekt. Będzie to w niektórych przypadkach (na przykład dla małych liczb całkowitych), i nie będzie dla innych (na przykład dużych liczb całkowitych).

Lekcja, której należy się nauczyć z powyższego przykładu, polega na tym, że trzeba bardzo uważać, aby użyć == dla typu referencyjnego. Używaj go tylko wtedy, gdy chcesz naprawdę chcesz przetestować, czy dwa odniesienia odnoszą się do tego samego obiektu. Nie używaj go, jeśli chcesz po prostu przetestować, czy obiekty są "równe" bez obciążenia wywołaniem equals().

(Należy również pamiętać, że String jest inny rodzaj gdzie == zamierza daje złą odpowiedź w wielu sytuacjach, patrz How do I compare strings in Java?.)

+0

'==' na elementach prymitywnych sprawdza tylko wartości i ignoruje typy. 'int x = 5; długi y = 5L; bajt b = 5; x == y; b == x; 'Obie zwracają true. – arun

+1

Nie "ignoruje" typów. Jeden lub drugi z operandów jest promowany do typu drugiego. Poza tym powiedziałem "wartości typu" ... –

Powiązane problemy