В Java мне говорят, что при проверке нуля следует использовать == вместо .equals (). В чем причины этого?
В Java мне говорят, что при проверке нуля следует использовать == вместо .equals (). В чем причины этого?
Ответы:
Это две совершенно разные вещи. ==
сравнивает ссылку на объект, если таковая имеется, содержащуюся в переменной. .equals()
проверяет, равны ли два объекта согласно их контракту, что означает равенство. Вполне возможно, что два разных экземпляра объекта будут «равны» в соответствии с их контрактом. И еще есть небольшая деталь: поскольку equals
это метод, если вы попытаетесь вызвать его по null
ссылке, вы получите файл NullPointerException
.
Например:
class Foo {
private int data;
Foo(int d) {
this.data = d;
}
@Override
public boolean equals(Object other) {
if (other == null || other.getClass() != this.getClass()) {
return false;
}
return ((Foo)other).data == this.data;
}
/* In a real class, you'd override `hashCode` here as well */
}
Foo f1 = new Foo(5);
Foo f2 = new Foo(5);
System.out.println(f1 == f2);
// outputs false, they're distinct object instances
System.out.println(f1.equals(f2));
// outputs true, they're "equal" according to their definition
Foo f3 = null;
System.out.println(f3 == null);
// outputs true, `f3` doesn't have any object reference assigned to it
System.out.println(f3.equals(null));
// Throws a NullPointerException, you can't dereference `f3`, it doesn't refer to anything
System.out.println(f1.equals(f3));
// Outputs false, since `f1` is a valid instance but `f3` is null,
// so one of the first checks inside the `Foo#equals` method will
// disallow the equality because it sees that `other` == null
public int data
?
Object
. Однако он переопределяется большим количеством классов JDK. Но дело не в реализации, а в семантике. (Примечание: JDK7 очень устарел.)
если вы вызываете .equals()
на null
вы получитеNullPointerException
Поэтому всегда рекомендуется проверять нулевое значение перед вызовом метода, где бы он ни применялся.
if(str!=null && str.equals("hi")){
//str contains hi
}
Также см
if ("hi".equals(str))
.
someObject.equals(null)
вызовет a, NullPointerException
даже не вводя метод equals.
Objects.equals(a, b)
Это не вызовет NullPointerException, но это все еще зависит от метода «равенства» для «a» и «b»
В дополнение к принятому ответу ( https://stackoverflow.com/a/4501084/6276704 ):
Начиная с Java 1.7, если вы хотите сравнить два объекта, которые могут быть нулевыми, я рекомендую эту функцию:
Objects.equals(onePossibleNull, twoPossibleNull)
java.util.Objects
Этот класс состоит из статических служебных методов для работы с объектами. Эти утилиты включают в себя нулевые безопасные или нулевые методы для вычисления хэш-кода объекта, возврата строки для объекта и сравнения двух объектов.
Начиная с: 1.7
В Java 0 или null - это простые типы, а не объекты.
Метод equals () не предназначен для простых типов. Простые типы могут быть сопоставлены с помощью ==.
Согласно источникам, не имеет значения, что использовать для реализации метода по умолчанию:
public boolean equals(Object object) {
return this == object;
}
Но equals
в кастомном классе нельзя быть уверенным .
equals
может только возвращать false
или вызывать NullPointerException
(или что-то другое, если equals
метод переопределения не имеет смысла).
Object.equals является нулевым безопасным, однако имейте в виду, что если два объекта имеют значение NULL, object.equals вернет true, поэтому обязательно проверьте, что сравниваемые объекты не являются нулевыми (или содержат нулевые значения), прежде чем использовать object.equals для сравнение.
String firstname = null;
String lastname = null;
if(Objects.equals(firstname, lastname)){
System.out.println("equal!");
} else {
System.out.println("not equal!");
}
Приведенный выше фрагмент примера вернет равенство!
Поскольку equal является функцией, производной от класса Object, эта функция сравнивает элементы класса. если вы используете его с null, он вернет false, потому что содержимое класса не равно null. Кроме того, == сравнивает ссылку на объект.
false
или NullPointerException
(если equals
не переопределить что-то плохое).
вот пример, где, str != null
но str.equals(null)
при использованииorg.json
JSONObject jsonObj = new JSONObject("{field :null}");
Object field = jsonObj.get("field");
System.out.println(field != null); // => true
System.out.println( field.equals(null)); //=> true
System.out.println( field.getClass()); // => org.json.JSONObject$Null
EDIT:
вот класс org.json.JSONObject $ Null :
/**
* JSONObject.NULL is equivalent to the value that JavaScript calls null,
* whilst Java's null is equivalent to the value that JavaScript calls
* undefined.
*/
private static final class Null {
/**
* A Null object is equal to the null value and to itself.
*
* @param object
* An object to test for nullness.
* @return true if the object parameter is the JSONObject.NULL object or
* null.
*/
@Override
public boolean equals(Object object) {
return object == null || object == this;
}
}
field.equals(null)
возвращается истина. Это нарушает обычное поведение Java и, следовательно, сбивает с толку. Он должен работать только для field.equals("null")
, по крайней мере, с моей точки зрения. Не знаю, почему разработчики библиотеки подумали, что это было бы хорошо поддержать.
str != null
и str.equals(null)
вернуться true
при использовании org.json .»?
jsonObject
содержит ключ "field", поэтому field
он не равен null, у него есть ссылка, которая содержит json.org.JSONObject$Null
объект
Null
такому же, null
и использовал бы "null"
вместо этого. Но я думаю, они сделали это, чтобы не требовать строк. Но даже с этой Lib, field.equals(null)
по - прежнему почти всегда вопрос: P.
Так что я никогда не запутаюсь и избегаю проблем с этим решением:
if(str.trim().length() <=0 ) {
// is null !
}
""
имеющая длину 0) полностью отличается от null
ссылки (т.е. без строки).
Ваш код нарушает закон Деметры. Поэтому лучше провести рефакторинг самой конструкции. В качестве обходного пути вы можете использовать Optional
obj = Optional.ofNullable(object1)
.map(o -> o.getIdObject11())
.map(o -> o.getIdObject111())
.map(o -> o.getDescription())
.orElse("")
выше - это проверить иерархию объекта, поэтому просто используйте
Optional.ofNullable(object1)
если у вас есть только один объект для проверки
Надеюсь это поможет !!!!
Вы всегда могли сделать
if (str == null || str.equals(null))
Это сначала проверит ссылку на объект, а затем проверит сам объект, если ссылка не равна нулю.
x.equals(null)
.
equals()
и посмотреть. Когда вы попробуете, это сразу станет очевидно