Java: равно и ==
Давайте посмотрим, что у нас есть 2 ссылки на экземпляры пользовательских классов a и b в Java. Может ли быть ситуация, когда a == b, но a.equals(b) возвращает false?
8 ответов
Конечно! Реализация .equals()
полностью до класса, так что я мог бы написать:
class Foo
public boolean equals(Object other) {
return false;
}
}
Теперь не имеет значения, какие два экземпляра вы проходите - даже один и тот же экземпляр дважды - я всегда буду говорить, что они не равны.
Это особенно глупо, но это показывает, что вы можете получить false
результат от .equals()
за один и тот же объект дважды.
Обратите внимание, что мы говорим здесь о том, что может произойти, а не о том, что должно произойти. Ни один класс не должен реализовывать .equals
метод, который утверждает, что объект не равен самому себе. Для доверенного кода разумно предположить, что этого никогда не произойдет.
if a == b
затем a.equals(b)
должно быть правдой. И если a.equals(b)
тогда возможно a == b
но не обязательно.
==
Оператор просто проверить, если оба ссылаются на один и тот же объект. В то время как equals
выполняет логику, которую вы реализовали. Последний может быть переопределен, первый - оператор из языка, и такой, который не может быть переопределен в Java.
Рекомендации
В чем разница между оператором == и equals ()? (с хэш-кодом ()???)
Отjava.lang.Object
документация:
Метод equals реализует отношение эквивалентности для ненулевых ссылок на объекты:
- Это рефлексивно: для любого ненулевого ссылочного значения x, x.equals(x) должно возвращать true.
- Это симметрично: для любых ненулевых ссылочных значений x и y x.equals (y) должен возвращать true тогда и только тогда, когда y.equals (x) возвращает true.
- Это транзитивно: для любых ненулевых ссылочных значений x, y и z, если x.equals (y) возвращает true, а y.equals(z) возвращает true, тогда x.equals(z) должен возвращать true.
- Это непротиворечиво: для любых ненулевых ссылочных значений x и y множественные вызовы x.equals (y) последовательно возвращают true или последовательно возвращают false при условии, что никакая информация, используемая в сравнениях сравнения на объектах, не изменяется.
- Для любого ненулевого ссылочного значения x, x.equals (null) должен возвращать false.
Да просто перегруз equals
делать что-то глупое. например
class Foo {
@Override
boolean equals(Object rhs) { return false; }
}
Очевидно, что можно написать код, который делает это, как указывали другие ответы.
Однако это также всегда логическая ошибка в коде, поскольку она нарушает неявный общий контракт функции equals().
Объект всегда должен быть равен самому себе, поэтому если (a==b)
затем a.equals(b)
должен всегда возвращать истину.
Ya we can overload the .equals
function to give the desired output. but there is no case where ==
returns true while .equals
возвращает ложь
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));
}
}
Выход ложный ложный
equals
метод может быть переопределен для обеспечения пользовательских функций, отличных от типичного ==
метод. Кроме того, некоторые типы, такие как Strings
не вернет true при использовании метода ==. Вы должны использовать .equals
или же .compareTo
(равно, когда возвращает 0).
Это должно обеспечить некоторую дополнительную помощь
Да, легко
public class Wrong{
public boolean equals(Object other)
{
return false;
}
}
Конечно, это полностью нарушает нормальные правила реализации .equals()
- см. Javadocs - но ничто не остановит вас, кроме здравого смысла.
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, чтобы получить что-то, что не является переменной класса. Например, значение из базы данных в два конкретных времени или случайное число. Надеюсь, что прояснит ваше дело