Правильный способ включения суперкласса в реализацию объекта Guava Objects.hashcode()?

Возможно, тупой вопрос, но я не хочу это испортить. Скажем, у меня есть два класса Java, Class1 и Class2, где Class2 extends Class1. Я хочу переопределить Object.hashcode() с помощью Guava для обоих классов. Для суперкласса у меня есть

@Override
public int hashCode() {
    return Objects.hashcode(mField1, mField2);
}

Для Class2, какой правильный способ реализовать hashcode(), который учитывает членов класса1? Это так?

@Override
public int hashcode() {
    return Objects.hashcode(super.hashcode(), mField3, mField4);
}  

Это SEEMS для меня, но я ищу некоторую проверку. Джошуа Блох не рассматривает эту ситуацию в Эффективной Java, и документы Guava также не являются.

Ответ 1

Да, это выглядит правильно. Было бы так же, если у вас был Objects.hashCode(f1, f2, f3, f4). Если вы посмотрите на реализацию, это похоже на result += 31 * result + hashcodeOfCurrentObject. Это означает, что ваш результат будет 31 + супер хэш-код, который не совсем то же самое, но не будет проблемой.

Ответ 2

Эффективная Java справляется с этой ситуацией... говоря, что вы не должны этого делать. Пункт 8:

Оказывается, что это фундаментальная проблема эквивалентности отношений в объектно-ориентированных языках. Нет возможности расширить экземпляр класса и добавить компонент значения при сохранении равный контракт, если вы не готовы отказаться от преимуществ объектно-ориентированная абстракция.

(Следствие: те же рассуждения применимы к hashCode().)

Ответ 3

Хотя предложение Божо действительно, я предпочитаю этот подход:

@Override
public int hashCode() {
    return Objects.hashcode(mField1, getParentField1(), getParentField2());
}