Coerenza nella lingua. Avere un operatore che agisce in modo diverso può sorprendere il programmatore. Java non consente agli utenti di sovraccaricare gli operatori, pertanto l'uguaglianza di riferimento è l'unico significato ragionevole per ==
tra gli oggetti.
In Java:
- Tra tipi numerici,
==
confronta l'uguaglianza numerica
- Tra i tipi booleani,
==
confronta l'uguaglianza booleana
- Tra oggetti,
==
confronta l'identità di riferimento
- Utilizza
.equals(Object o)
per confrontare i valori
Questo è tutto. Regola semplice e semplice per identificare quello che vuoi. Tutto questo è trattato in sezione 15.21 del JLS . Comprende tre sottosezioni facili da capire, implementare e ragionare.
Una volta consenti il sovraccarico di ==
, il il comportamento esatto non è qualcosa che puoi guardare al JLS e mettere il dito su un elemento specifico e dire "così funziona", il codice può diventare difficile da ragionare. Il comportamento esatto di ==
può sorprendere per un utente. Ogni volta che lo vedi, devi tornare indietro e controllare per vedere cosa significa in realtà.
Poiché Java non consente il sovraccarico degli operatori, è necessario un test di uguaglianza dei valori che sia possibile sovrascrivere la definizione di base di. Pertanto, è stato affidato a queste scelte progettuali. ==
nei test Java numerici per i tipi numerici, l'uguaglianza booleana per i tipi booleani e l'uguaglianza di riferimento per tutto il resto (che può sovrascrivere .equals(Object o)
per fare tutto ciò che vogliono per l'uguaglianza dei valori).
Questo non è un problema di "c'è un caso d'uso per una particolare conseguenza di questa decisione progettuale", ma piuttosto "questa è una decisione di progettazione per facilitare queste altre cose, questa è una conseguenza di esso."
Interning delle stringhe , ne è un esempio. Secondo JLS 3.10.5 , tutti i letterali stringa sono internati. Altre stringhe sono internate se si invoca .intern()
su di esse. Quel "foo" == "foo"
è vero è una conseguenza delle decisioni di progettazione prese per minimizzare l'impronta di memoria occupata dai letterali String. Oltre a ciò, l'interning delle stringhe è qualcosa che è a livello di JVM che ha un po 'di esposizione per l'utente, ma nella stragrande maggioranza dei casi, non dovrebbe essere qualcosa che riguarda il programmatore (e i casi d'uso per i programmatori non erano qualcosa che era in cima alla lista per i designer quando si considera questa funzione).
Le persone faranno notare che +
e +=
sono sovraccaricati per String. Tuttavia, questo non è né qui né lì. Resta il caso che se ==
ha un significato di uguaglianza di valore per String (e solo String), occorrerebbe un metodo diverso (che esiste solo in String) per l'uguaglianza di riferimento. Inoltre, questo complicherebbe inutilmente i metodi che accettano Object e aspettano che ==
si comporti in un modo e .equals()
per comportarsi in un altro, richiedendo agli utenti casi speciali tutti i quei metodi per String.
Il contratto coerente per ==
su Oggetti è che è solo l'uguaglianza di riferimento e che .equals(Object o)
esiste per tutti gli oggetti che dovrebbero testare per l'uguaglianza di valore. Complicare questo complica troppe cose.