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 реализует отношение эквивалентности для ненулевых ссылок на объекты:

  1. Это рефлексивно: для любого ненулевого ссылочного значения x, x.equals(x) должно возвращать true.
  2. Это симметрично: для любых ненулевых ссылочных значений x и y x.equals (y) должен возвращать true тогда и только тогда, когда y.equals (x) возвращает true.
  3. Это транзитивно: для любых ненулевых ссылочных значений x, y и z, если x.equals (y) возвращает true, а y.equals(z) возвращает true, тогда x.equals(z) должен возвращать true.
  4. Это непротиворечиво: для любых ненулевых ссылочных значений x и y множественные вызовы x.equals (y) последовательно возвращают true или последовательно возвращают false при условии, что никакая информация, используемая в сравнениях сравнения на объектах, не изменяется.
  5. Для любого ненулевого ссылочного значения 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, чтобы получить что-то, что не является переменной класса. Например, значение из базы данных в два конкретных времени или случайное число. Надеюсь, что прояснит ваше дело

Другие вопросы по тегам