Как по умолчанию.equals и.hashCode будут работать для моих классов?
Скажи у меня есть свой класс
public class MyObj { /* ... */ }
У него есть некоторые атрибуты и методы. Он не реализует равно, не реализует хэш-код.
Как только мы вызываем equals и hashCode, каковы реализации по умолчанию? Из класса объектов? И что они? Как будет работать значение по умолчанию? Как будет работать хэш-код по умолчанию и что вернет? == просто проверит, ссылаются ли они на один и тот же объект, так что это легко, но как насчет методов equals() и hashCode()?
6 ответов
Да, реализация по умолчанию - Object (вообще говоря; если вы наследуете от класса, который переопределил equals и / или hashCode, то вы будете использовать эту реализацию вместо этого).
Из документации:
equals
Метод equals для класса Object реализует максимально различающее возможное отношение эквивалентности на объектах; то есть для любых ненулевых ссылочных значений x и y этот метод возвращает true, если и только если x и y ссылаются на один и тот же объект (x == y имеет значение true).
hashCode
Насколько это практически целесообразно, метод hashCode, определенный классом Object, возвращает разные целые числа для разных объектов. (Это обычно реализуется путем преобразования внутреннего адреса объекта в целое число, но этот метод реализации не требуется языком программирования JavaTM.)
От Object
в одной из реализаций JVM:
public boolean equals(Object object) {
return this == object;
}
public int hashCode() {
return VMMemoryManager.getIdentityHashCode(this);
}
В обоих случаях это просто сравнение адресов памяти рассматриваемых объектов.
Существуют стандартные реализации equals()
а также hashCode()
в объекте. Если вы не предоставите свою собственную реализацию, они будут использованы. За equals()
это означает ==
сравнение: объекты будут равны только в том случае, если они абсолютно одинаковые. За hashCode()
У Javadoc есть хорошее объяснение.
Для получения дополнительной информации см. Эффективная Java, Глава 3 (pdf), пункт 8.
Если вы не предоставите свою собственную реализацию, будет использоваться одна из производных от Object. Это нормально, если только вы не планируете помещать экземпляры вашего класса в, например, HashSet (любую коллекцию, которая фактически использует hashCode()), или что-то, что должно проверять равенство объекта (например, метод contains() HashSet). В противном случае он будет работать некорректно, если вы об этом просите.
Довольно просто представить собственную реализацию этих методов благодаря HashCodeBuilder и EqualsBuilder из Apache Commons Lang.
Да, из Object
класс, так как ваш класс неявно расширяет объект. equals
просто возвращается this == obj
, hashCode
Реализация является родной. Просто догадка - он возвращает указатель на объект.
IBM Developerworks говорит:
При реализации по умолчанию две ссылки равны, только если они ссылаются на один и тот же объект. Аналогично, реализация по умолчанию hashCode(), предоставляемая Object, получается путем сопоставления адреса памяти объекта с целочисленным значением.
Тем не менее, чтобы быть уверенным в точных деталях реализации Java-версии конкретного поставщика, вероятно, лучше всего смотреть в качестве источника (если он доступен).