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