Spójność w języku. Posiadanie operatora, który działa inaczej, może zaskoczyć programistę. Java nie pozwala użytkownikom przeciążać operatorów - dlatego równość odwołań jest jedynym rozsądnym znaczeniem ==
między obiektami.
W Javie:
- Między typami
==
numerycznymi porównuje równość liczbową
- Między typami
==
boolowskimi porównuje równość boolowską
- Między obiektami
==
porównuje tożsamość odniesienia
- Służy
.equals(Object o)
do porównywania wartości
Otóż to. Prosta reguła i prosta identyfikacja tego, czego chcesz. Wszystko to opisano w sekcji 15.21 JLS . Zawiera trzy podrozdziały, które są łatwe do zrozumienia, wdrożenia i uzasadnienia.
Gdy pozwolisz na przeładowanie==
, dokładne zachowanie nie jest czymś, co możesz spojrzeć na JLS i położyć palec na konkretnym elemencie i powiedzieć „tak to działa”, kod może być trudny do uzasadnienia. Dokładne zachowanie ==
może być zaskakujące dla użytkownika. Za każdym razem, gdy go zobaczysz, musisz wrócić i sprawdzić, co to właściwie oznacza.
Ponieważ Java nie pozwala na przeciążanie operatorów, potrzebny jest test równości wartości, który można zastąpić podstawową definicją. Tak więc było to wymagane przez te wybory projektowe. ==
w testach Java numeryczne dla typów liczbowych, równość boolowska dla typów boolowskich i równość referencyjna dla wszystkich innych elementów (które mogą zastąpić .equals(Object o)
robienie, co chcą, dla równości wartości).
Nie jest to kwestia „czy istnieje przypadek użycia konkretnej konsekwencji tej decyzji projektowej”, ale raczej „jest to decyzja projektowa mająca na celu ułatwienie tych innych rzeczy, jest to jej konsekwencja”.
Internowanie ciągów , jest jednym z takich przykładów. Zgodnie z JLS 3.10.5 wszystkie literały łańcuchowe są internowane. Inne łańcuchy są internalizowane, jeśli ktoś .intern()
je wywołuje . To "foo" == "foo"
prawda, jest konsekwencją decyzji projektowych podejmowanych w celu zminimalizowania zajmowanego miejsca w pamięci przez literały String. Poza tym internowanie ciągów jest czymś na poziomie JVM, który ma trochę ekspozycji na użytkownika, ale w przeważającej większości przypadków nie powinno być czymś, co dotyczy programisty (a przypadki użycia dla programistów nie były coś, co było wysoko na liście projektantów przy rozważaniu tej funkcji).
Ludzie to zauważą +
i +=
są przeciążeni ciągiem. Tego jednak nie ma ani tu, ani tam. Pozostaje przypadek, że jeśli ==
ma wartość równości wartości dla String (i tylko String), potrzebna byłaby inna metoda (która istnieje tylko w String) dla równości odniesienia. Co więcej, niepotrzebnie skomplikowałoby to metody, które pobierają Object i oczekują, że będą ==
się zachowywać w jeden sposób, a .equals()
inne będą wymagały od użytkowników specjalnego przypadku wszystkich tych metod dla String.
Konsekwentna umowa ==
dotycząca Obiektów polega na tym, że jest to tylko równość odniesienia i .equals(Object o)
istnieje dla wszystkich obiektów, które powinny testować równość wartości. Skomplikowanie tego komplikuje zdecydowanie zbyt wiele rzeczy.
==
jest równość obiektu ieq
równość odniesienia ( ofps.oreilly.com/titles/9780596155957/… ).