Висновки
Розділивши чотири довільно обрані приклади реалізації рівностей (), що ми робимо?
Перш за все: є два суттєво різні способи виконання перевірки відповідності типу в реалізації рівняння (). Клас може дозволяти зіставляти змішані типи об’єктів над- і підкласу за допомогою оператора instanceof, або клас може розглядати об'єкти іншого типу як нерівні за допомогою тесту getClass (). Наведені вище приклади добре проілюстрували, що реалізація рівнянь () за допомогою getClass (), як правило, більш надійна, ніж ті, що реалізують, використовуючи instanceof.
Тест instanceof є правильним лише для підсумкових класів або, якщо принаймні метод дорівнює (), є остаточним у суперкласі. Останній по суті означає, що жоден підклас не повинен поширювати стан надкласу, а може додавати лише функціональність або поля, які не мають значення для стану та поведінки об'єкта, наприклад, перехідні або статичні поля.
Реалізація, що використовує тест getClass (), з іншого боку, завжди відповідає договору equals (); вони правильні та надійні. Однак вони семантично дуже відрізняються від реалізацій, які використовують тест instanceof. Реалізації, що використовують getClass (), не дозволяють порівнювати під- з об'єктами надкласового класу, навіть коли підклас не додає жодних полів і навіть не хотів би замінити рівняння (). Таке "тривіальне" розширення класу, наприклад, було б додаванням методу друку налагодження у підкласі, визначеному саме для цієї "тривіальної" мети. Якщо суперклас забороняє порівняння змішаного типу через перевірку getClass (), то тривіальне розширення було б не порівнянне з його суперкласом. Чи повністю це проблема чи ні, залежить від семантики класу та мети розширення.
x instanceof SomeClass
помилковий, якщоx
єnull
. Отже, другий синтаксис не потребує перевірки нуля.