Правильный способ включить суперкласс в реализацию Guava Objects.hashcode()?
Возможно, глупый вопрос, но я не хочу облажаться. Допустим, у меня есть два класса Java, Class1
а также Class2
, где Class2 extends Class1
, Я хочу переопределить Object.hashcode()
используя гуаву для обоих классов. Для суперкласса у меня есть
@Override
public int hashCode() {
return Objects.hashcode(mField1, mField2);
}
Для Class2, как правильно реализовать hashcode(), который учитывает членов Class1? Это так?
@Override
public int hashcode() {
return Objects.hashcode(super.hashcode(), mField3, mField4);
}
Это кажется мне правильным, но я ищу подтверждение. Джошуа Блох не рассматривает эту ситуацию в "Эффективной Java", а также документы по Guava.
3 ответа
Да, это выглядит правильно. Было бы то же самое, если бы вы имели Objects.hashCode(f1, f2, f3, f4)
, Если вы посмотрите на реализацию, это что-то вроде result += 31 * result + hashcodeOfCurrentObject
, Это означает, что ваш результат будет 31 + супер хэш-код, который не совсем то же самое, но не будет проблемой.
Эффективная Java решает эту проблему... говоря, что вы не должны этого делать. Пункт 8:
Оказывается, это фундаментальная проблема отношений эквивалентности в объектно-ориентированных языках. Невозможно расширить инстанцируемый класс и добавить компонент value при сохранении контракта equals, если вы не хотите отказаться от преимуществ объектно-ориентированной абстракции.
(Следствие: то же самое относится и к hashCode().)
Хотя предложение Божо справедливо, я предпочитаю такой подход:
@Override
public int hashCode() {
return Objects.hashcode(mField1, getParentField1(), getParentField2());
}