Java: equals и ==
Увидим, что у нас есть 2 ссылки на экземпляры пользовательского класса a и b в Java.
Может ли быть такая ситуация, когда
a == b, но a.equals(b) возвращает false?
Ответы
Ответ 1
Конечно! Реализация .equals()
полностью соответствует классу, поэтому я мог бы написать:
class Foo
public boolean equals(Object other) {
return false;
}
}
Теперь не имеет значения, какие два экземпляра вы передаете - даже тот же самый экземпляр дважды - я всегда буду говорить, что они не равны.
Эта настройка является глупой, но она иллюстрирует, что вы можете получить результат false
из .equals()
для одного и того же объекта дважды.
Обратите внимание, что мы говорим здесь о том, что может, а не о том, что должно. Ни один класс не должен реализовывать метод .equals
, который утверждает, что объект не равен самому себе. Для доверенного кода разумно предположить, что этого никогда не произойдет.
Ответ 2
Да, просто перегрузите equals
, чтобы сделать что-то глупое. например.
class Foo {
@Override
boolean equals(Object rhs) { return false; }
}
Ответ 3
if a == b
, тогда a.equals(b)
должно быть истинным. И если a.equals(b)
, то возможно a == b
, но не обязательно.
Оператор ==
просто проверяет, ссылаются ли оба на один и тот же объект. Пока equals
выполняет логику, которую вы реализовали. Последний может быть переопределен, первый из них является оператором с языка и не может быть переопределен в Java.
Ссылки
В чем разница между оператором == и equals()? (с hashcode()))
Из java.lang.Object
документация:
Метод equals реализует отношение эквивалентности на непустых ссылки на объекты:
- Это рефлексивно: для любого ненулевого опорного значения х, x.equals(х) должна возвращать истинное.
- Он симметричен: для любых непустых опорных значений x и y x.equals(y) должен возвращать true тогда и только тогда, когда y.equals(x) возвращает правда.
- Это транзитивно: для любых непустых опорных значений x, y и z, если x.equals(y) возвращает true, а y.equals(z) возвращает true, тогда x.equals(z) должно возвращать true.
- Это непротиворечиво: для любых непустых опорных значений x и y множественные вызовы x.equals(y) последовательно возвращают true или последовательно возвращать false, если никакая информация не используется на равных сопоставления по объектам.
- Для любого ненулевого опорного значения х, x.equals(NULL) должен возвращать ложь.
Ответ 4
Очевидно, что возможно писать код, который делает это, как указывали другие ответы.
Однако он также всегда является логической ошибкой в коде, поскольку он нарушает неявный общий контракт функции equals().
Объект всегда должен быть равен самому себе, поэтому если (a==b)
, то a.equals(b)
должен всегда возвращать true.
Ответ 5
Ya мы можем перегрузить функцию .equals
, чтобы дать желаемый результат. но нет случая, когда ==
возвращает true, а .equals
возвращает false.
class s {
int a;
}
class dev {
public static void main(String args[]) {
s a = new s();
s b = new s();
System.out.println(a == b);
System.out.println(a.equals(b));
}
}
Output
false
false
Ответ 6
Да, легко:
public class Wrong{
public boolean equals(Object other)
{
return false;
}
}
Конечно, это полностью нарушает нормальные правила реализации .equals()
- см. Javadocs - но вам нечего остановить, кроме хороших чувство.
Ответ 7
Метод equals
может быть переопределен для обеспечения пользовательских функций, отличных от типичного метода ==
. Кроме того, некоторые типы, такие как Strings
, не будут возвращать true при использовании метода ==. Вы должны использовать .equals
или .compareTo
(равный при возврате 0).
Это должно предоставить дополнительную дополнительную помощь
Ответ 8
package com.stackOverFlow;
import java.util.Date;
public class SampleClass {
public static int myint = 1;
private SampleClass() {
};
public Integer returnRandom() {
return myint++;
}
private static SampleClass _sampleClass;
public static SampleClass getInstance() {
if (_sampleClass == null) {
_sampleClass = new SampleClass();
}
return _sampleClass;
}
@Override
public boolean equals(Object other) {
if (this.returnRandom().equals(((SampleClass) other).returnRandom())) {
return true;
}
return false;
}
}
package com.stackOverFlow;
public class Run {
/**
* @param args
*/
public static void main(String[] args) {
// TODO Auto-generated method stub
SampleClass a = SampleClass.getInstance();
SampleClass b = SampleClass.getInstance();
if(a==b){
System.out.println("references are same as they are pointing to same object");
if(!a.equals(b)){
System.out.println("two random number Instance will never be same");
}
}
}
}
Это можно понять на Практическом примере. где класс singeleton всегда будет возвращать вам одну и ту же ссылку, и вы можете переопределить метод equals, чтобы получить что-то, что не является переменной класса. например, значение из базы данных в два конкретных периода времени или случайное число. Надеюсь, что очистит ваше дело.