2009-10-18 12 views

risposta

2

Per i tipi di riferimento, == confronta il riferimento effettivo (in cui si trova l'oggetto in memoria) dove il metodo equals esegue un confronto dei dati.

La JVM a volte "String intern" le stringhe immutabili per motivi di prestazioni. Causando questo:

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

imparato un nuovo concetto - internato! – lft93ryt

1

L'operatore '==' lavora sul tipo primitivo che hai, che nel caso di oggetti di riferimento è il riferimento stesso. Quello è a == b confronterà i valori per i tipi primitivi come int, ma confronterà il riferimento (non il valore) per i tipi di riferimento. Due oggetti di tipo di riferimento che non sono uguali ma hanno lo stesso valore restituiscono true quando viene chiamato il metodo equals(), ma a == b sarà falso.

Per i tipi primitivi, quando si chiama un metodo, il tipo viene precedentemente convertito (in box) in un tipo di riferimento e quindi viene chiamato il metodo. Ciò significa che per i tipi primitivi a == b si otterrà lo stesso valore di a.equals(b), ma in quest'ultimo caso verranno creati due oggetti box temporanei prima di chiamare il metodo equals(). Ciò renderà l'operazione più costosa in termini di tempo della CPU, il che può o meno rappresentare un problema a seconda di dove accade.

Vale a dire, per confrontare i valori di tipo primitivo è necessario utilizzare ==, mentre per confrontare i valori del tipo di riferimento è necessario utilizzare il metodo .equals().

Lo stesso accade con il metodo toString(). Quando viene chiamato su un oggetto del tipo di riferimento, chiamerà il metodo appropriato e produrrà una stringa. Quando viene richiamato un tipo primitivo, il tipo verrà autoboxato e quindi il metodo verrà chiamato nell'oggetto temporaneo. In questo caso, è possibile chiamare il metodo statico toString() appropriato (ad esempio, per la chiamata interna Integer.toString(myint)) per evitare di creare l'oggetto temporaneo.

+0

'a.equals (b)' non verrà compilato se 'a' è un tipo primitivo. – ajb

7

Per i tipi regolari (tra cui String):

  • == confronta riferimenti a oggetti. Verifica se due riferimenti a oggetti sono uguali; cioè se si riferiscono allo stesso oggetto.
  • equals(Object) test se questo oggetto è "uguale a" un altro. Cosa significa "uguale a" dipende da come la classe dell'oggetto definisce l'uguaglianza. La classe java.lang.Object definisce equals(other) come this == other, ma molte classi sovrascrivono questa definizione.
  • toString() fornisce una conversione semplice dell'oggetto a una stringa. Il formato e il contenuto della stringa risultante sono specifici della classe e (dal punto di vista del contratto java.lang.Object) non ci sono garanzie che sia significativo.

Per (true) tipi primitivi:

  • == confronta valori del tipo, e
  • equals() e toString() non sono definiti. Java non consente di chiamare un metodo su un valore primitivo.

Tuttavia, questo è complicato dal fatto che in alcuni contesti linguaggio Java dice che un tipo primitivo può essere "autoboxed" per dare un esempio di tipo corrispondente involucro del tipo primitivo; per esempio. int corrisponde a java.lang.Integer e così via. Per le classi involucro:

  • == è definita la stessa come per qualsiasi altro tipo di riferimento,
  • equals() confronta i valori avvolti, e
  • toString() formatta i valori avvolto.

Il bastone tra le ruote è illustrata dal seguente:

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. 

La ragione per cui l'ultimo a volte fallisce è che la JLS non garantisce che autoboxing un dato valore di base darà sempre lo stesso involucro oggetto. Sarà in alcuni casi (ad esempio per i numeri interi piccoli) e non per gli altri (ad esempio i grandi numeri interi).

La lezione da trarre dall'esempio sopra riportato è che bisogna fare molta attenzione all'utilizzo di == su un tipo di riferimento. Utilizzatelo solo quando si in realtà si desidera verificare se due riferimenti si riferiscono allo stesso oggetto. Non usarlo se vuoi solo verificare se gli oggetti sono "uguali" senza il sovraccarico di chiamare equals().

(Si noti inoltre che String è un altro tipo in cui == sta per dare la risposta sbagliata in molte situazioni, vedi How do I compare strings in Java?.)

+0

'==' sulle primitive controlla solo i valori e ignora i tipi. 'int x = 5; lunga y = 5L; byte b = 5; x == y; b == x; 'Entrambi restituiscono true. – arun

+1

Non sta "ignorando" i tipi. Uno o l'altro degli operandi viene promosso al tipo dell'altro. Inoltre, ho detto "valori del tipo" ... –

Problemi correlati