Coerenza nella lingua. Avere un operatore che agisce diversamente può essere sorprendente per il programmatore. Java non consente agli utenti di sovraccaricare gli operatori, pertanto l'uguaglianza di riferimento è l'unico significato ragionevole ==
tra gli oggetti.
All'interno di Java:
- Tra tipi numerici,
==
confronta l'uguaglianza numerica
- Tra tipi booleani,
==
confronta l'uguaglianza booleana
- Tra oggetti,
==
confronta l'identità di riferimento
- Utilizzare
.equals(Object o)
per confrontare i valori
Questo è tutto. Regola semplice e semplice per identificare ciò che vuoi. Tutto ciò è coperto nella sezione 15.21 del JLS . Comprende tre sottosezioni che sono facili da capire, implementare e ragionare.
Una volta che si consente il sovraccarico di==
, il comportamento esatto non è qualcosa che si può guardare al JLS e mettere il dito su un elemento specifico e dire "è così che funziona", il codice può diventare difficile da ragionare. L'esatto comportamento di ==
può essere sorprendente per un utente. Ogni volta che lo vedi, devi tornare indietro e controllare per vedere cosa significa effettivamente.
Poiché Java non consente il sovraccarico degli operatori, è necessario un modo per avere un test di uguaglianza di valore di cui è possibile ignorare la definizione di base. Pertanto, è stato richiesto da queste scelte progettuali. ==
in Java test numerici per tipi numerici, uguaglianza booleana per tipi booleani e uguaglianza di riferimento per tutto il resto (che può sovrascrivere .equals(Object o)
per fare ciò che vogliono per l'uguaglianza di valore).
Non si tratta di "esiste un caso d'uso per una particolare conseguenza di questa decisione progettuale", ma piuttosto "questa è una decisione progettuale per facilitare queste altre cose, ne è una conseguenza".
Lo string interning , ne è un esempio. Secondo JLS 3.10.5 , tutti i valori letterali di stringa sono internati. Altre stringhe vengono internate se si invoca .intern()
su di esse. Questo "foo" == "foo"
è vero è una conseguenza delle decisioni di progettazione prese per minimizzare il footprint di memoria assunto dai letterali String. Oltre a ciò, lo string interning è qualcosa 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 lo erano qualcosa che era in cima alla lista per i progettisti quando si considera questa funzione).
La gente lo farà notare +
e +=
sono sovraccarichi di 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), si avrebbe bisogno di un metodo diverso (che esiste solo in String) per l'uguaglianza di riferimento. Inoltre, ciò complicherebbe inutilmente i metodi che prendono Object e si aspettano ==
di comportarsi in un modo e .equals()
di comportarsi in un altro, richiedendo agli utenti casi speciali tutti quei metodi per String.
Il contratto coerente per gli ==
oggetti è che si tratta solo di uguaglianza di riferimento e che .equals(Object o)
esiste per tutti gli oggetti che dovrebbero verificare l'uguaglianza di valore. Complicare ciò complica troppe cose.
==
trova l'uguaglianza degli oggetti edeq
è l'uguaglianza di riferimento ( ofps.oreilly.com/titles/9780596155957/… ).