У 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()і побачити. Коли ви спробуєте, це миттєво стане очевидним