Как по умолчанию .equals и .hashCode будут работать для моих классов? - PullRequest
100 голосов
/ 14 ноября 2010

Скажи, что у меня есть свой класс

public class MyObj { /* ... */ }

Имеет некоторые атрибуты и методы. Он НЕ реализует равные, НЕ реализует hashCode.

Как только мы вызываем equals и hashCode, каковы реализации по умолчанию? Из класса объектов? И что они? Как будет работать значение по умолчанию? Как будет работать хэш-код по умолчанию и что вернет? == просто проверит, ссылаются ли они на один и тот же объект, так что это легко, но как насчет методов equals () и hashCode ()?

Ответы [ 6 ]

91 голосов
/ 14 ноября 2010

Да, реализация по умолчанию - Object (вообще говоря; если вы наследуете от класса, который переопределил equals и / или hashCode, тогда вы будете использовать эту реализацию вместо этого).

Из документации:

equals

Метод equals для класса Object реализует максимально различающее возможное отношение эквивалентности для объектов;то есть для любых ненулевых ссылочных значений x и y этот метод возвращает true тогда и только тогда, когда x и y ссылаются на один и тот же объект (x == y имеет значение true).

hashCode

Насколько это практически целесообразно, метод hashCode, определенный в классе Object, возвращает разные целые числа для разных объектов.(Это обычно реализуется путем преобразования внутреннего адреса объекта в целое число, но этот метод реализации не требуется языком программирования JavaTM.)

45 голосов
/ 14 ноября 2010

С Object в одной из реализаций JVM:

public boolean equals(Object object) {
    return this == object;
}

public int hashCode() {
    return VMMemoryManager.getIdentityHashCode(this);
}

В обоих случаях это просто сравнение адресов памяти рассматриваемых объектов.

10 голосов
/ 14 ноября 2010

В Object есть стандартные реализации equals() и hashCode().Если вы не предоставите собственную реализацию, они будут использованы.Для equals() это означает сравнение ==: объекты будут равны только в том случае, если они абсолютно одинаковые.Для hashCode() Javadoc имеет хорошее объяснение.

Для получения дополнительной информации см. Эффективная Java, Глава 3 (pdf), пункт 8.

1 голос
/ 14 ноября 2010

Если вы не предоставите свою собственную реализацию, будет использоваться одна из производных от Object. Это нормально, если только вы не планируете помещать экземпляры своего класса в, например, HashSet (любую коллекцию, которая фактически использует hashCode ()), или что-то, что должно проверять равенство объекта (то есть метод hasashSet contains ()). В противном случае он будет работать некорректно, если вы об этом просите.

Довольно просто обеспечить собственную реализацию этих методов благодаря HashCodeBuilder и EqualsBuilder из Apache Commons Lang .

1 голос
/ 14 ноября 2010

Да, из класса Object, поскольку ваш класс неявно расширяет объект.equals просто возвращает this == obj.hashCode Реализация является родной.Просто догадка - он возвращает указатель на объект.

0 голосов
/ 14 ноября 2010

IBM developerworks говорит:

При реализации по умолчанию две ссылки равны, только если они ссылаются на один и тот же объект.Аналогично, реализация по умолчанию hashCode (), предоставляемая Object, получается путем сопоставления адреса памяти объекта с целочисленным значением.

Однако, чтобы быть уверенным в точных деталях реализации для конкретного поставщикаВерсия Java, вероятно, лучше всего смотреть как источник (если он доступен)

...