Назад к вопросам
СБЕР
Senior
4
public class ClassA { int a; @Override public boolean equals(Object obj) { //реализация if (this == obj) return true; if (!obj instanceof(ClassA) return false; ClassA other = (ClassA) obj; return this.a == other.a; } } public class ClassB extends ClassA { int b; @Override public boolean equals(Object obj) { //реализация if (this == obj) return true; if (!obj instanceof(ClassB) return false; if (!super.equals(obj)) return false; ClassB other = (ClassB) obj; return this.b == other.b; } } ClassB b1 = new ClassB(a: 10, b: 20); ClassB b2 = new ClassB(a: 10, b: 20); assertTrue(b1.equals(b2));
Компании, где спрашивали
Ответ от нейросети
sobes.tech AI
В представленном коде есть несколько ошибок и потенциальных проблем при переопределении метода equals в классах ClassA и ClassB.
- Синтаксическая ошибка:
if (!obj instanceof(ClassA) return false;
Правильный синтаксис:
if (!(obj instanceof ClassA)) return false;
- Нарушение контракта equals при наследовании:
Метод
equalsдолжен быть:
- рефлексивным
- симметричным
- транзитивным
- консистентным
- не равным
null
В текущей реализации ClassB.equals вызывает super.equals(obj), но при этом проверяет instanceof ClassB. Это может привести к проблемам с симметрией, если сравнивать объекты ClassA и ClassB.
- Рекомендации:
- При переопределении
equalsв наследниках стоит учитывать, что сравнивать объекты разных классов не следует. - Можно использовать паттерн "canEqual" или делать
equalsфинальным в базовом классе.
Пример исправленного equals для ClassA:
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
ClassA other = (ClassA) obj;
return this.a == other.a;
}
И для ClassB:
@Override
public boolean equals(Object obj) {
if (this == obj) return true;
if (obj == null || getClass() != obj.getClass()) return false;
if (!super.equals(obj)) return false;
ClassB other = (ClassB) obj;
return this.b == other.b;
}
Такой подход гарантирует, что объекты сравниваются только если они одного класса, что сохраняет контракт equals.
Также важно переопределить hashCode вместе с equals.