Как я проверяю на пустые указатели в '==' перегрузка оператора без бесконечной рекурсии?

NullPointerException s - исключения, возникающие при попытке использовать ссылку, которая указывает на отсутствие местоположения в памяти (null), как если бы она ссылалась на объект. Вызов метода по нулевой ссылке или попытка получить доступ к полю нулевой ссылки вызовет функцию NullPointerException. Они наиболее распространены, но другие способы перечислены на странице NullPointerException javadoc.

Вероятно, самый быстрый пример кода, который я мог бы придумать для иллюстрации NullPointerException, be:

public class Example {

    public static void main(String[] args) {
        Object obj = null;
        obj.hashCode();
    }

}

В первой строке внутри main я явно устанавливаю ссылку Object obj равной null. Это означает, что у меня есть ссылка, но она не указывает на какой-либо объект. После этого я пытаюсь обработать ссылку так, как если бы она указывала на объект, вызывая метод на нем. Это приводит к NullPointerException, потому что нет кода для выполнения в местоположении, на которое указывает ссылка.

(Это техничность, но я думаю, что она упоминает: ссылка, которая указывает на null, равна 't то же, что и указатель C, указывающий на недопустимую ячейку памяти. Нулевой указатель буквально не указывает на в любом месте , который отличается от указаний на местоположение, которое оказывается недопустимым.)

110
задан Alexei Levenkov 19 June 2014 в 23:05
поделиться

6 ответов

Используйте ReferenceEquals:

Foo foo1 = null;
Foo foo2 = new Foo();
Assert.IsFalse(foo1 == foo2);

public static bool operator ==(Foo foo1, Foo foo2) {
    if (object.ReferenceEquals(null, foo1))
        return object.ReferenceEquals(null, foo2);
    return foo1.Equals(foo2);
}
132
ответ дан bluish 24 November 2019 в 03:15
поделиться

Бросок для возражения в методе перегрузки:

public static bool operator ==(Foo foo1, Foo foo2) {
    if ((object) foo1 == null) return (object) foo2 == null;
    return foo1.Equals(foo2);
}
19
ответ дан Andrew Jones 24 November 2019 в 03:15
поделиться

Попробуйте Object.ReferenceEquals(foo1, null)

Так или иначе, я не рекомендовал бы перегрузиться == оператор; это должно использоваться для сравнения ссылок и использования Equals для "семантических" сравнений.

4
ответ дан Jason Plank 24 November 2019 в 03:15
поделиться

Используйте ReferenceEquals. От форумы MSDN :

public static bool operator ==(Foo foo1, Foo foo2) {
    if (ReferenceEquals(foo1, null)) return ReferenceEquals(foo2, null);
    if (ReferenceEquals(foo2, null)) return false;
    return foo1.field1 == foo2.field2;
}
8
ответ дан Jon Adams 24 November 2019 в 03:15
поделиться

Если у меня есть overrided bool Equals(object obj), и я хочу, чтобы оператор == и Foo.Equals(object obj) дал тот же ответ, я обычно реализую != оператор как это:

public static bool operator ==(Foo foo1, Foo foo2) {
  return object.Equals(foo1, foo2);
}
public static bool operator !=(Foo foo1, Foo foo2) {
  return !object.Equals(foo1, foo2);
}

оператор == будет тогда после выполнения всех пустых проверок на меня, заканчивают тем, что звонили foo1.Equals(foo2), что я переопределил, чтобы сделать фактическую проверку, если эти два равны.

4
ответ дан Hallgrim 24 November 2019 в 03:15
поделиться

Можно попытаться использовать свойство объекта и поймать получающийся NullReferenceException. Если свойство, которое Вы пробуете, наследовано или переопределено от Объекта, то это работает на любой класс.

public static bool operator ==(Foo foo1, Foo foo2)
{
    //  check if the left parameter is null
    bool LeftNull = false;
    try { Type temp = a_left.GetType(); }
    catch { LeftNull = true; }

    //  check if the right parameter is null
    bool RightNull = false;
    try { Type temp = a_right.GetType(); }
    catch { RightNull = true; }

    //  null checking results
    if (LeftNull && RightNull) return true;
    else if (LeftNull || RightNull) return false;
    else return foo1.field1 == foo2.field2;
}
-5
ответ дан The Digital Gabeg 24 November 2019 в 03:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: