Послідовність всередині мови. Наявність оператора, який діє по-різному, може здивувати програміста. Java не дозволяє користувачам перевантажувати операторів - тому рівність посилань є єдиним розумним значенням ==
між об'єктами.
В межах Java:
- Між числовими типами
==
порівнює числову рівність
- Між булевими типами
==
порівнює булева рівність
- Між об'єктами
==
порівнює посилання на ідентичність
- Використовуйте
.equals(Object o)
для порівняння значень
Це воно. Просте правило і просте визначення того, що ви хочете. Це все висвітлено у розділі 15.21 JLS . Він складається з трьох підрозділів, які легко зрозуміти, впровадити та обґрунтувати.
Як тільки ви дозволите перевантаження==
, точна поведінка не є чимось, на що ви можете звернути увагу на JLS і покласти пальцем на певний предмет і сказати "ось як це працює", про це може стати важко обґрунтувати. Точна поведінка користувача ==
може здивувати користувача. Кожного разу, коли ви його бачите, вам доведеться повертатися назад і перевіряти, що це насправді означає.
Оскільки Java не дозволяє перевантажувати операторів, потрібен спосіб провести тест рівності значень, на який можна переосмислити базове визначення. Таким чином, це було доручено цим вибором дизайну. ==
в Java тестує числові типи для числових типів, булева рівність для булевих типів і опорна рівність для всього іншого (що може замінити .equals(Object o)
виконання всього, що вони хочуть, за рівності значення).
Це не питання "чи є випадок використання певного наслідку цього дизайнерського рішення", а, скоріше, "це проектне рішення для полегшення цих інших речей, це є наслідком цього".
Струнне інтернування - один із таких прикладів. Згідно з JLS 3.10.5 , всі рядкові літерали інтерновані. Інші рядки інтерновані, якщо один викликає .intern()
їх. Це "foo" == "foo"
правда, це наслідок дизайнерських рішень, прийнятих для мінімізації сліду пам’яті, прийнятого літералами String. Крім того, струнне інтернування - це те, що знаходиться на рівні JVM, що має незначну експозицію користувача, але в переважній більшості випадків не повинно бути те, що стосується програміста (а випадки використання для програмістів не були те, що було високо в списку для дизайнерів при розгляді цієї функції).
Люди вкажуть на це +
і +=
перевантажені для String. Однак цього немає ні тут, ні там. Залишається випадок, що якщо ==
має значення рівності значення для String (і лише String), для еталонної рівності знадобиться інший метод (який існує лише у String). Крім того, це зайво ускладнить методи, які сприймають Object і очікують, що ==
вони поводяться в один бік і .equals()
поводяться по-іншому, вимагаючи від користувачів спеціального випадку всіх цих методів для String.
Послідовний договір ==
на об’єкти полягає в тому, що це лише еталонна рівність і .equals(Object o)
існує для всіх об'єктів, які повинні перевірити ціннісну рівність. Ускладнення цього ускладнює занадто багато речей.
==
є об'єктна рівність іeq
є референтна рівність ( ofps.oreilly.com/titles/9780596155957/… ).