У 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
не вводячи метод рівних.
Objects.equals(a, b)
це не підвищить NullPointerException, але це все ще залежить від методу "рівності" "а" та "б"
Окрім прийнятої відповіді ( 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, тому обов'язково переконайтеся, що об'єкти, які ви порівнюєте, не є null (або утримуйте null значення), перш ніж використовувати object.equals для порівняння.
String firstname = null;
String lastname = null;
if(Objects.equals(firstname, lastname)){
System.out.println("equal!");
} else {
System.out.println("not equal!");
}
Приклад фрагмента вище буде повернутись рівним!
Оскільки рівним є функція, похідна від класу Object, ця функція порівнює елементи класу. якщо ви використовуєте його з 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
вона не є нульовою, вона має посилання, яке містить json.org.JSONObject$Null
об'єкт
Null
до цього, null
а використовував би "null"
натомість. Але я думаю, що вони зробили це, щоб уникнути необхідності струн. Але навіть з цією лібкою field.equals(null)
все ще майже завжди виникає проблема: P.
У вас код порушує закон Деметра. Ось чому краще переробляти саму конструкцію. Як вирішення, ви можете використовувати Необов’язково
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))
Це спочатку перевірить посилання на об'єкт, а потім перевірить сам об’єкт, надаючи посилання isnt null.
x.equals(null)
.
equals()
і побачити. Коли ви спробуєте, це миттєво стане очевидним