In Java I am told that when doing a null check one should use == instead of .equals(). What are the reasons for this?
16 Answers
They're two completely different things. == compares the object reference, if any, contained by a variable. .equals() checks to see if two objects are equal according to their contract for what equality means. It's entirely possible for two distinct object instances to be "equal" according to their contract. And then there's the minor detail that since equals is a method, if you try to invoke it on a null reference, you'll get a NullPointerException.
For instance:
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
7 Comments
public int data?Object, yes. It's overridden by a large number of the JDK classes, though. But the point about isn't about implementation, it's about semantics. (Side note: JDK7 is very out of date.)null isn't an object, it's an object reference (a blank one). It's the only object reference we can write literally in code. So Object a = null; Object b = null; means that a == b is true, because both variables contain the same object reference (the single universal blank one).In addition to the accepted answer (https://stackoverflow.com/a/4501084/6276704):
Since Java 1.7, if you want to compare two Objects which might be null, I recommend this function:
Objects.equals(onePossibleNull, twoPossibleNull)
java.util.Objects
This class consists of static utility methods for operating on objects. These utilities include null-safe or null-tolerant methods for computing the hash code of an object, returning a string for an object, and comparing two objects.
Since: 1.7
2 Comments
Object.equals() instead, when I use == in my code.if you invoke .equals() on null you will get NullPointerException
So it is always advisble to check nullity before invoking method where ever it applies
if(str!=null && str.equals("hi")){
//str contains hi
}
Also See
5 Comments
if ("hi".equals(str)).someObject.equals(null) will raise a NullPointerException without ever entering the equals method.Objects.equals(a, b) It won't raise NullPointerException, but it still depends on the "equal" method of the "a" and "b"In Java 0 or null are simple types and not objects.
The method equals() is not built for simple types. Simple types can be matched with ==.
3 Comments
Object.equals is null safe, however be aware that if two objects are null, object.equals will return true so be sure to check that the objects you are comparing aren't null (or hold null values) before using object.equals for comparison.
String firstname = null;
String lastname = null;
if(Objects.equals(firstname, lastname)){
System.out.println("equal!");
} else {
System.out.println("not equal!");
}
Example snippet above will return equal!
2 Comments
Objects.equals()According to sources it doesn't matter what to use for default method implementation:
public boolean equals(Object object) {
return this == object;
}
But you can't be sure about equals in custom class.
1 Comment
equals can only return false or cause a NullPointerException (or something different if the overriden equals method is nonsense).here is an example where str != null but str.equals(null) when using 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:
here is the org.json.JSONObject$Null class:
/**
* 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;
}
}
4 Comments
field.equals(null) returns true. This breaks usual Java behaviour and is therefore confusing. It should only work for field.equals("null"), at least in my point of view. I don't know why the library developers thought, that this would be good to support.str != null and str.equals(null) return true when using org.json."?jsonObject contains the "field" key that's why field isn't null, it has a reference which contains the json.org.JSONObject$Null objectNull like null and would use "null" instead. But I guess they did that to avoid requiring Strings. But even with that lib, field.equals(null) is still almost always an issue :P.Because equal is a function derived from Object class, this function compares items of the class. if you use it with null it will return false cause cause class content is not null. In addition == compares reference to an object.
1 Comment
false or NullPointerException (if equals is not overriden to something bad).So I never get confused and avoid problems with this solution:
if(str.trim().length() <=0 ) {
// is null !
}
You code breaks Demeter's law. That's why it's better to refactor the design itself. As a workaround, you can use Optional
obj = Optional.ofNullable(object1)
.map(o -> o.getIdObject11())
.map(o -> o.getIdObject111())
.map(o -> o.getDescription())
.orElse("")
above is to check to hierarchy of a object so simply use
Optional.ofNullable(object1)
if you have only one object to check
Hope this helps !!!!
Comments
You could always do
if (str == null || str.equals(null))
This will first check the object reference and then check the object itself providing the reference isnt null.
6 Comments
x.equals(null).
equals()and see. When you try it will instantly be obvious