Метод equ () не работает в Java
Следующий фрагмент кода не работает. Зачем? Это объекты одного и того же класса, и они имеют одинаковое значение переменной экземпляра. В чем проблема?
Pen bluePen = new Pen("Faber Castel");
Pen bluePen1 = new Pen("Faber Castel");
if( bluePen.equals(bluePen1) )
System.out.println("They are equal");
Выход пуст. Когда я это сделал:
Pen bluePen = new Pen();
Pen varPen = bluePen;
if( bluePen == varPen)
System.out.println(“They are identical”);
Нет проблем. Вывод "Они идентичны".
Я пытался понять разницу между == и методом equal(). Я прочитал различия этих двух вещей на этом сайте. Но я запутался из-за следующего фрагмента кода, который не работает должным образом:
Pen bluePen = new Pen("Faber Castel");
Pen bluePen1 = new Pen("Faber Castel");
if( bluePen.equals(bluePen1) )
System.out.println("They are equal");
Может ли кто-нибудь объяснить мне, почему приведенный выше код не выдает "Они равны"?
3 ответа
Из этого вопроса ( почему мы должны переопределить метод equals() в Java?) Вы можете прочитать, что Java по умолчанию сравнивает два объекта по адресу их памяти. Если вы создадите два экземпляра, оба экземпляра будут иметь разные адреса памяти. Следовательно, они не равны. (Суть в том, что метод работает, но не так, как вы ожидали)
Вот почему вы должны переопределить equals
метод в вашем Pen
класс, чтобы "сказать" Java, что если Pen.Name
равно, сам объект равен.
В Java, когда оператор "==" используется для сравнения 2 объектов, он проверяет, ссылаются ли объекты на одно и то же место в памяти. Другими словами, он проверяет, являются ли два имени объекта в основном ссылками на одну и ту же ячейку памяти.
Метод equals() на самом деле ведет себя так же, как и оператор "==", то есть он проверяет, ссылаются ли оба объекта на одно и то же место в памяти. Но метод equals на самом деле предназначен для сравнения содержимого двух объектов, а не их расположения в памяти.
, Вы даже можете переопределить метод equals(), чтобы определить себя, когда объект равен другому
Как вы определяете "равный"?
Java не знает ничего интуитивного в ваших объектах. Он может компилировать и запускать код, но не может сказать вам, какие члены важны при определении таких вещей, как равенство или порядок сортировки или что-то в этом роде. Это логика, которую вы должны определить. В отсутствие этой логики реализация по умолчанию - ссылочное равенство.
В вашем первом примере переменные ссылаются на два разных экземпляра объекта. Так что они не равны. Во втором примере переменные ссылаются на один и тот же экземпляр объекта. Так они равны.
Для определения равенства необходимо переопределить equals()
(а также hashcode()
) в вашем классе. Что-то вроде:
@Override
public int hashCode() {
// TODO: compute and return a hash code
}
@Override
public boolean equals(Object obj) {
// TODO: determine and return if the supplied instance is logically equal to the current instance
}
В Интернете есть много хороших примеров того, как эффективно реализовать эти методы. Фактически логика проста. hashCode()
должен возвращать значение, которое будет уникальным для любого "неравного" экземпляра объекта, вычисляемого на основе полей, используемых для определения равенства. А также equals()
следует определить это равенство из этих полей.
Общая концепция становится семантически очень важной, когда вы начинаете рассматривать, что представляют объекты в различных областях бизнес-логики. Например, что делает два Person
объекты равны? Если их имена совпадают? Очевидно, нет, потому что два человека могут иметь одинаковое имя. Сочетание их имени, адреса и номера телефона? Нету. (Мой брат и мой отец разделяли все эти атрибуты в течение 20 лет.) Какая комбинация атрибутов обеспечивает это Person
отличается от другого Person
? Ответ, вероятно, будет значительно отличаться между бизнес-доменами.