Java: diversi double e double in confronto

So che Double è una class wrapper, e racchiude il double numero. Oggi ho visto un’altra differenza principale:

 double a = 1.0; double b = 1.0; Double c = 1.0; Double d = 1.0; System.out.println(a == b); // true System.out.println(c == d); // false 

Così strano con me !!!

Quindi, se usiamo Double , ogni volta, dobbiamo fare qualcosa del genere:

 private static final double delta = 0.0001; System.out.println(Math.abs(cd) < delta); 

Non riesco a spiegare perché Double faccia direttamente il confronto sbagliato. Per favore, spiegami per me.

Grazie 🙂

c e d sono tecnicamente due oggetti diversi e l’operatore == confronta solo i riferimenti.

 c.equals(d) 

è migliore in quanto confronta valori, non riferimenti. Ma ancora non è l’ideale. Confrontare direttamente i valori in virgola mobile dovrebbe sempre prendere in considerazione alcuni errori (epsilon) ( Math.abs(c - d) < epsilon ).

Nota che:

 Integer c = 1; Integer d = 1; 

qui il confronto sarebbe true , ma è più complicato (cache interna intera, descritta in JavaDoc di Integer.valueOf() ):

Questo metodo memorizza sempre i valori nell'intervallo compreso tra -128 e 127 e può memorizzare nella cache altri valori al di fuori di questo intervallo.

Perché valueOf() ? Poiché questo metodo viene utilizzato implicitamente per implementare l'autoboxing:

 Integer c = Integer.valueOf(1); Integer d = Integer.valueOf(1); 

Guarda anche

  • Boxing strano in Java
  • Come confrontare correttamente due interi in Java?

Quando applicato a espressioni di un tipo di class, == eseguirà sempre un confronto di riferimento ( sezione JLS 15.21.3 ). Quindi questa linea:

 System.out.println(c == d); 

sta controllando se c e d riferiscono agli stessi oggetti. Auto-boxing in Java sempre (credo) crea un nuovo object per float e double (la situazione è più complicata per i tipi interi 1 ). Pertanto c e d riferiscono a oggetti diversi e quindi stampa false .

Se vuoi confrontare gli oggetti per l’uguaglianza, devi chiamare esplicitamente equals :

 System.out.println(c.equals(d)); 

Con il double , utilizza invece l’uguaglianza numerica, come specificato nella sezione 15.21.1 . Da qui la differenza di comportamento.


1 Per l’autoboxing integrale, i valori “piccoli” vengono memorizzati nella cache, pertanto il 5 autoboxing (ad esempio) restituirà sempre lo stesso riferimento. La definizione di “piccolo” è specifica dell’implementazione, ma è garantita nell’intervallo da -128 a 127. Per i dettagli, vedere la parte inferiore della sezione 5.1.7 .

Usa equals() per verificare l’uguaglianza di 2 oggetti. == controlla se i 2 riferimenti si riferiscono allo stesso object nella memoria.

Il controllo del contenuto è affidabile solo per == quando si controllano i tipi primitivi. Per i tipi di oggetti è sempre meglio usare il metodo equals :

 c.equals(d)