Самый простой способ - попробовать проверить нулевое значение equals()и посмотреть. Когда вы попробуете, это сразу станет очевидно
Горан Йович
Между прочим, поиск в Google с ключевыми словами "java null check" (без кавычек) дал мне как одно из лучших совпадений в этой теме , которая содержит ту же информацию, что и ответы здесь.
Митч Шварц
Ответы:
179
Это две совершенно разные вещи. ==сравнивает ссылку на объект, если таковая имеется, содержащуюся в переменной. .equals()проверяет, равны ли два объекта согласно их контракту, что означает равенство. Вполне возможно, что два разных экземпляра объекта будут «равны» в соответствии с их контрактом. И еще есть небольшая деталь: поскольку equalsэто метод, если вы попытаетесь вызвать его по nullссылке, вы получите файл NullPointerException.
Например:
classFoo{privateint data;Foo(int d){this.data = d;}@Overridepublicboolean equals(Object other){if(other ==null|| other.getClass()!=this.getClass()){returnfalse;}return((Foo)other).data ==this.data;}/* In a real class, you'd override `hashCode` here as well */}Foo f1 =newFoo(5);Foo f2 =newFoo(5);System.out.println(f1 == f2);// outputs false, they're distinct object instancesSystem.out.println(f1.equals(f2));// outputs true, they're "equal" according to their definitionFoo f3 =null;System.out.println(f3 ==null);// outputs true, `f3` doesn't have any object reference assigned to itSystem.out.println(f3.equals(null));// Throws a NullPointerException, you can't dereference `f3`, it doesn't refer to anythingSystem.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
@Xepoch: Нет, я обычно не создаю общедоступные поля (хотя в любом случае это не имеет значения для данного примера). Зачем?
TJ Crowder
@TJ Crowder "Это две совершенно разные вещи ..." в общем да. Однако реализация обоих по умолчанию одинакова, если я правильно понимаю. Глядя на исходный код, .equals () в основном выполняет проверку ==. hg.openjdk.java.net/jdk7/jdk7/jdk/file/tip/src/share/classes/...
Ayush
1
@Ayush - Да, это по умолчанию Object. Однако он переопределяется большим количеством классов JDK. Но дело не в реализации, а в семантике. (Примечание: JDK7 очень устарел.)
TJ Crowder
Хорошо, это имеет смысл, просто хотел прояснить.
Аюш,
38
если вы вызываете .equals()на nullвы получитеNullPointerException
Поэтому всегда рекомендуется проверять нулевое значение перед вызовом метода, где бы он ни применялся.
Ваш пример обычно лучше писать как if ("hi".equals(str)).
ColinD
3
@ user368186: дело не в том, включает ли метод equals проверку на null. Если ваша ссылка на объект имеет значение null, тогда вызов someObject.equals(null)вызовет a, NullPointerExceptionдаже не вводя метод equals.
Дэйв Коста
2
@ColinD Согласен, просто демонстрация здесь
Джигар Джоши
2
Всегда желательно любой ценой избегать нулевых значений, поэтому вам вообще не нужны нулевые проверки;).
fwielstra
2
Вы всегда можете использовать Objects.equals(a, b)Это не вызовет NullPointerException, но это все еще зависит от метода «равенства» для «a» и «b»
Начиная с Java 1.7, если вы хотите сравнить два объекта, которые могут быть нулевыми, я рекомендую эту функцию:
Objects.equals(onePossibleNull, twoPossibleNull)
java.util.Objects
Этот класс состоит из статических служебных методов для работы с объектами. Эти утилиты включают в себя нулевые безопасные или нулевые методы для вычисления хэш-кода объекта, возврата строки для объекта и сравнения двух объектов.
Это имеет значение, поскольку equalsможет только возвращать falseили вызывать NullPointerException(или что-то другое, если equalsметод переопределения не имеет смысла).
Том
2
Если мы используем метод => .equals
if(obj.equals(null))// Which mean null.equals(null) when obj will be null.
Когда ваш obj будет нулевым, он выдаст исключение нулевой точки.
Object.equals является нулевым безопасным, однако имейте в виду, что если два объекта имеют значение NULL, object.equals вернет true, поэтому обязательно проверьте, что сравниваемые объекты не являются нулевыми (или содержат нулевые значения), прежде чем использовать object.equals для сравнение.
Как указано в JavaDoc (всегда разумно их читать): Consequently, if both arguments are null, true is returned. ...:)
Томас
1
Поскольку equal является функцией, производной от класса Object, эта функция сравнивает элементы класса. если вы используете его с null, он вернет false, потому что содержимое класса не равно 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.
*/privatestaticfinalclassNull{/**
* 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.
*/@Overridepublicboolean equals(Object object){return object ==null|| object ==this;}}
Проблема здесь в том, что field.equals(null)возвращается истина. Это нарушает обычное поведение Java и, следовательно, сбивает с толку. Он должен работать только для field.equals("null"), по крайней мере, с моей точки зрения. Не знаю, почему разработчики библиотеки подумали, что это было бы хорошо поддержать.
Tom
Кстати, в вашем первом предложении есть грамматическая проблема, и непонятно, что вы под ним имеете в виду. Вы имеете в виду «Вот пример, где str != nullи str.equals(null)вернуться trueпри использовании org.json .»?
Tom
Я думаю, это потому, что jsonObjectсодержит ключ "field", поэтому fieldон не равен null, у него есть ссылка, которая содержит json.org.JSONObject$Null объект
dina
Да, но я бы не стал относиться к Nullтакому же, nullи использовал бы "null"вместо этого. Но я думаю, они сделали это, чтобы не требовать строк. Но даже с этой Lib, field.equals(null)по - прежнему почти всегда вопрос: P.
Tom
0
Так что я никогда не запутаюсь и избегаю проблем с этим решением:
Кроме того, пустая строка ( ""имеющая длину 0) полностью отличается от nullссылки (т.е. без строки).
Томас
0
Я столкнулся с этим случаем вчера вечером.
Я определяю это просто так:
Не существует метода equals () для null Итак, вы не можете вызвать несуществующий метод, если у вас его нет
- >>> Это причина, по которой мы используем == для проверки null
equals()
и посмотреть. Когда вы попробуете, это сразу станет очевидноОтветы:
Это две совершенно разные вещи.
==
сравнивает ссылку на объект, если таковая имеется, содержащуюся в переменной..equals()
проверяет, равны ли два объекта согласно их контракту, что означает равенство. Вполне возможно, что два разных экземпляра объекта будут «равны» в соответствии с их контрактом. И еще есть небольшая деталь: посколькуequals
это метод, если вы попытаетесь вызвать его поnull
ссылке, вы получите файлNullPointerException
.Например:
источник
public int data
?Object
. Однако он переопределяется большим количеством классов JDK. Но дело не в реализации, а в семантике. (Примечание: JDK7 очень устарел.)если вы вызываете
.equals()
наnull
вы получитеNullPointerException
Поэтому всегда рекомендуется проверять нулевое значение перед вызовом метода, где бы он ни применялся.
Также см
источник
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(null, null)
вернетсяtrue
- имейте это в виду.В Java 0 или null - это простые типы, а не объекты.
Метод equals () не предназначен для простых типов. Простые типы могут быть сопоставлены с помощью ==.
источник
Что произойдет, если foo имеет значение null?
Вы получаете исключение NullPointerException.
источник
Если переменная Object имеет значение null, для нее нельзя вызвать метод equals (), поэтому проверка ссылки на объект на null является правильной.
источник
Если вы попытаетесь вызвать equals для ссылки на нулевой объект, вы получите исключение с нулевым указателем.
источник
Согласно источникам, не имеет значения, что использовать для реализации метода по умолчанию:
Но
equals
в кастомном классе нельзя быть уверенным .источник
equals
может только возвращатьfalse
или вызыватьNullPointerException
(или что-то другое, еслиequals
метод переопределения не имеет смысла).Если мы используем метод => .equals
Когда ваш obj будет нулевым, он выдаст исключение нулевой точки.
поэтому мы должны использовать ==
он сравнит ссылки.
источник
Object.equals является нулевым безопасным, однако имейте в виду, что если два объекта имеют значение NULL, object.equals вернет true, поэтому обязательно проверьте, что сравниваемые объекты не являются нулевыми (или содержат нулевые значения), прежде чем использовать object.equals для сравнение.
Приведенный выше фрагмент примера вернет равенство!
источник
Consequently, if both arguments are null, true is returned. ...
:)Поскольку equal является функцией, производной от класса Object, эта функция сравнивает элементы класса. если вы используете его с null, он вернет false, потому что содержимое класса не равно null. Кроме того, == сравнивает ссылку на объект.
источник
false
илиNullPointerException
(еслиequals
не переопределить что-то плохое).вот пример, где,
str != null
ноstr.equals(null)
при использованииorg.json
EDIT: вот класс org.json.JSONObject $ Null :
источник
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.Так что я никогда не запутаюсь и избегаю проблем с этим решением:
источник
""
имеющая длину 0) полностью отличается отnull
ссылки (т.е. без строки).Я столкнулся с этим случаем вчера вечером.
Я определяю это просто так:
источник
Ваш код нарушает закон Деметры. Поэтому лучше провести рефакторинг самой конструкции. В качестве обходного пути вы можете использовать Optional
выше - это проверить иерархию объекта, поэтому просто используйте
если у вас есть только один объект для проверки
Надеюсь это поможет !!!!
источник
Вы всегда могли сделать
Это сначала проверит ссылку на объект, а затем проверит сам объект, если ссылка не равна нулю.
источник
x.equals(null)
.