Правильный способ включить суперкласс в реализацию 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());
}
Другие вопросы по тегам