2011-12-29 17 views
19

Consideriamo prima le seguenti espressioni in Java.Il metodo equals() in Java funziona in modo imprevisto sul tipo di dati Long

Integer temp = new Integer(1); 
System.out.println(temp.equals(1)); 

if(temp.equals(1)) 
{ 
    System.out.println("The if block executed."); 
} 

Queste istruzioni funzionano perfettamente. Non c'è dubbio al riguardo. L'espressione temp.equals(1) viene valutata come true come previsto e l'unica istruzione all'interno del blocco if viene eseguita di conseguenza.


Ora, quando cambio il tipo di dati da Integer al Long, la dichiarazione temp1.equals(1) è inaspettatamente valutata a false come segue.

Long temp1 = new Long(1); 
System.out.println(temp1.equals(1)); 

if(temp1.equals(1)) 
{ 
    System.out.println("The if block executed."); 
} 

Queste sono le istruzioni equivalenti a quelli menzionati nel frammento precedente solo il tipo di dati è stata modificata e si comportano esattamente opposto.

L'espressione temp1.equals(1) viene valutata su false e di conseguenza, l'unica istruzione all'interno del blocco if non viene eseguita quale è il contrario delle precedenti istruzioni. Come?

+0

La documentazione dice che '.equals' restituisce true solo se entrambi gli oggetti sono di tipo' long'. – mc10

+0

Ho provato 'if (temp1.longValue() == 1)' e 'if (temp1.equals (1l)' funzionavano entrambi come previsto – Lion

risposta

31

Stai comparando uno Long in uno int. Il Javadoc per java.lang.Long#equals dice che il metodo di equals

confronto tra questo oggetto per l'oggetto specificato. Il risultato è true se e solo se l'argomento non è null ed è un oggetto Long che contiene lo stesso valore lungo di questo oggetto.

Invece di cercare System.out.println(new Long(1).equals(1L)); Ora che si sta confrontando un Long ad un Long invece di un Long ad un Integer, verrà stampata true.

+0

Anche '1L' funziona? – TheLQ

+0

@TheLQ Stai chiedendo se puoi do 'new Long (1L)'? Sì, è possibile. '1L' rappresenta fondamentalmente un tipo' long'. Poiché il costruttore 'Long' accetta' long's, accetta '1L' come argomento del costruttore. –

5

Il valore letterale 1 è non un long, è un int. Prova il codice di cui sopra, con questo, invece:

System.out.println(temp1.equals(1L)); 

E

if (temp1.equals(1L)) 

Come si può vedere, mettendo L dopo che il valore letterale 1 indica che si tratta di un long, e quindi i confronti funzionano come previsto.

0

È possibile confrontare i valori Long/intero senza uting equals(). Questo è necessario solo quando si confrontano le stringhe per quanto ne so.

3

Secondo Javadoc's page on Long, il .equals method viene valutato come true solo se

  1. L'argomento è un oggetto Long
  2. Se (1) è vera, allora gli Long oggetti devono avere valori uguali

Nel tuo scenario, 1 è un int, non un oggetto Long, quindi non riesce (1), e quindi re, valuta false. Se è necessario testare su un long, utilizzare invece 1L.

2

Questo comportamento è coerente con autoboxing convertire il 1 ad un Integer che confronta quindi uguale all'altro Integer(1). Il confronto di un Long in un Integer produce false.

Se si usa 1L da confrontare con Long sarebbe cedere true.

4

Il motivo per cui è possibile eseguire il confronto è a causa del boxing automatico in Java.

Il metodo effettivo che si sta chiamando è questo:

http://docs.oracle.com/javase/1.4.2/docs/api/java/lang/Long.html#equals(java.lang.Object)

che sta confrontando l'oggetto lungo per qualche altro oggetto, non un int reale primitivo.

Cosa succede quando si chiama il metodo è che il vostro primitivo integer(1) si sta autoboxed in un Object(Integer) così allora si sta effettivamente chiamando:

new Long(1).equals(new Integer(1)); 

che è il motivo per cui non riesce.

Questo è il motivo per cui se si chiama

new Long(1).equals(1L) 

questo dovrebbe funzionare, perché Java autobox la 1L (primitiva long, non int) in un oggetto Long, non un oggetto Integer.

1

L'implementazione del metodo della classe equals()Long illustra il motivo per cui:

public boolean equals(Object obj) { 
    if (obj instanceof Long) { 
     return value == ((Long)obj).longValue(); 
    } 
    return false; 
} 
3

Java è essere pigro.

Quando si esegue il confronto seguente, java esegue automaticamente il cast dell'int per un valore long (poiché un valore lungo può contenere qualsiasi valore che un int può contenere). E il confronto è tra due lunghi e non due interi.

int i = 1; 
long l = 1L; 
boolean b = i == l; 

Java è in grado di fare questo perché le informazioni sul tipo su i e l è noto al momento della compilazione e quando si esegue il confronto.Tuttavia, quando si utilizza la versione in scatola il tipo può essere noto al momento della compilazione, ma non quando si esegue il confronto. Questo perché il confronto deve essere eseguito all'interno di un metodo uguale, e poiché equals assume Object come parametro, le informazioni sul tipo vengono perse. Quindi Java è pigro e controlla solo se due numeri in box sono uguali se sono entrambi istanze della stessa classe Number (ad esempio, sia Intero, o entrambi Long, o entrambi Double, ecc ...).

saltato fuori che l'unico modo completamente affidabile per confrontare due numeri di tipo sconosciuto in fase di esecuzione è quello di convertire sia per stringhe e sia per BigDecimal e quindi di utilizzare il metodo compareTo (e non uguale). Anche se sapete che otterrete sempre long e intimità, allora la vita è più semplice, basta fare quanto segue.

Number n0 = new Long(1L); 
Number n1 = new Integer(1); 
boolean equal = n0.longValue() == n1.longValue(); 
+0

It sarebbe bello se potessi aggiungere un esempio e la fonte ufficiale per il "metodo completamente affidabile" menzionato per confrontare il valore di due numeri di tipo sconosciuto. Grazie e upvote comunque! –

2

lungo temp1 = new Lunga (1); System.out.println (temp1.equals (1));

if (temp1.equals (1)) { System.out.println ("Il blocco if eseguito."); }

in questo codice temp1.equals(1) di comparazione di un oggetto Long oggetto Integer che dà il risultato falso, possiamo correggerlo utilizzando 1L anziché 1 ,,, es temp1.equals(1L), facendo questo stiamo confrontando Long oggetto con a Long e restituisce VERO

1

Il metodo equals in Java.lang.Long inizia inizialmente con un controllo instanceOf Long solo dopo che il valore è stato confrontato.

public boolean equals(Object obj) { 
    if (obj instanceof Long) { 
     return value == ((Long)obj).longValue(); 
    }   
    return false; 
} 

Quindi, se avete intenzione di usare e valore intero INT il posto di un valore a lungo allora il primo controllo ha esito negativo e quindi si otterrà falso come il risultato.

Problemi correlati