Java null check why use == instead of .equals() - java

In Java I am told that when doing a null check one should use == instead of .equals(). What are the reasons for this?

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

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
difference-between-equals-and == in Java

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

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 ==.

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!

foo.equals(null)
What happens if foo is null?
You get a NullPointerException.

If an Object variable is null, one cannot call an equals() method upon it, thus an object reference check of null is proper.

If you try calling equals on a null object reference, then you'll get a null pointer exception thrown.

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.

If we use=> .equals method
if(obj.equals(null))
// Which mean null.equals(null) when obj will be null.
When your obj will be null it will throw Null Point Exception.
so we should use ==
if(obj == null)
it will compare the references.

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;
}
}

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.

So I never get confused and avoid problems with this solution:
if(str.trim().length() <=0 ) {
// is null !
}

I have encountered this case last night.
I determine that simply that:
Don't exist equals() method for null
So, you can not invoke an inexistent method if you don't have
-->>> That is reason for why we use == to check 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 !!!!

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.

Related

Comparing the value of two null objects without NPE

This is an extremely basic question but why is the following code returning a null pointer exception?
String a = null;
String b = null;
System.out.println(a.equals(b));
According to the docs here:
http://docs.oracle.com/javase/7/docs/api/java/util/Objects.html#equals(java.lang.Object,%20java.lang.Object)
the .equals() function is first checking for null before comparing values. Shouldn't it return true since they are both null?
The method you linked to takes in two objects and is a static method. You need to call it like Objects.equals(a, b). Instead you are calling .equals() on a null object which throws NPE
Shouldn't it return true since they are both null?
nop. since a is a null-referenced object, invoking ANY instance method on that object will throw a NPE
so what you can do:
if you are still on java 6 do
System.out.println(a == null ? b == null : a.equals(b));
and since java 7
System.out.println(Objects.equals(a, b));
I usually write following method,
private boolean equalsWithNull(String first, String second){
return ((first!=null&&second!=null && first.equals(second)) || (first==null && second==null));
}
Objects::equals is the best option, but you can use
Optional.ofNullable(a).equals(Optional.ofNullable(b))
as well. However I don't really see any cases when you will choose Optional approach instead of Objects
you can check both values instead of reference,
String a = null;
String b = null;
System.out.println(a == b ? "true":"false");
it returns true.

What is the cleanest way to compare an int with a potentially null Integer in Java?

Map<String,Integer> m;
m = new TreeMap<String,Integer>();
Is it good practice to add the following cast just to avoid the null pointer exception when m.get() is null.
System.out.println( ((Integer) 8).equals( m.get("null") ) ); // returns false
Alternatively with a prior null check it starts to look a bit ugly.
System.out.println( m.contains("null") != null && m.get("null").equals( 8 ) );
Is there a better way to write this? Thanks.
The == operator doesn't compare values, but references.
You should use the .equals() method, instead, applied to the Integer variable (for which you are sure that is not null and NPE won't be thrown):
Integer eight = 8; //autoboxed
System.out.println(eight.equals(m.get("null")));
This will print false even the m.get("null") returns null.
No, because it will not work. You can't compare two Integer with ==, as that compares references and not the integer values. See more info in this question
You'll need a helper method, such as:
boolean safeIntegerCompare(Integer a, int b)
{
if (a != null)
return a.intValue() == b;
return false;
}
I try to avoid casts whenever possible, so I'd rather use the following, which also looks nicer in my opinion:
Integer.valueOf(8).equals(m.get("null"))
If only one of the arguments may be null (as is the case when you're comparing an unknown value to a constant), use equals() like this:
Integer foo = Integer.valueOf(8); // you could write Integer foo = 8; here too but I prefer to avoid autoboxing
if (foo.equals(m.get("x"))) { //will never throw an NPE because foo is never null
...
}
Note that your example isn't going to work in general because comparing non-primitive values with == only returns true if they refer to the same object instance. (Which in this case might even be true for very specific reasons but most of the time it isn't.)
To expand the accepted answer: i find myself having to check the equality of 2 Integer variables which might or might not be null.
So my solution would be:
boolean equals =
Optional.ofNullable(objectA.getNullableInteger()).equals(Optional.ofNullable(objectB.getNullableInteger());
You can use Objects.equals
int foo = 1;
Integer bar = null;
Objects.equals(foo, bar);

How to handle null string in java

I am .net programmer and completely new in java. I am facing problem in handling null string in java. I am assigning value from string array to string variable completeddate.
I tried all this but that didn't work.
String COMPLETEDATE;
COMPLETEDATE = country[23];
if(country[23] == null && country[23].length() == 0)
{
// ...
}
if (COMPLETEDATE.equals("null"))
{
// ...
}
if(COMPLETEDATE== null)
{
// ...
}
if(COMPLETEDATE == null || COMPLETEDATE.equals("null"))
{
// ...
}
For starters...the safest way to compare a String against a potentially null value is to put the guaranteed not-null String first, and call .equals on that:
if("constantString".equals(COMPLETEDDATE)) {
// logic
}
But in general, your approach isn't correct.
The first one, as I commented, will always generate a NullPointerException is it's evaluated past country[23] == null. If it's null, it doesn't have a .length property. You probably meant to call country[23] != null instead.
The second approach only compares it against the literal string "null", which may or may not be true given the scope of your program. Also, if COMPLETEDDATE itself is null, it will fail - in that case, you would rectify it as I described above.
Your third approach is correct in the sense that it's the only thing checking against null. Typically though, you would want to do some logic if the object you wanted wasn't null.
Your fourth approach is correct by accident; if COMPLETEDDATE is actually null, the OR will short-circuit. It could also be true if COMPLETEDDATE was equal to the literal "null".
To check null string you can use Optional in Java 8 as below:
import Optional
import java.util.Optional;
import it as above
String str= null;
Optional<String> str2 = Optional.ofNullable(str);
then use isPresent() , it will return false if str2 contains NULL otherwise true
if(str2.isPresent())
{
//If No NULL
}
else
{
//If NULL
}
reference: https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html
It is not entirely clear what you are asking, but to check if a String variable is null, use the following statement.
if(myString==null)
This checks whether the object reference is null.
The following statement, which you have written is incorrect for two reasons.
if (COMPLETEDATE.equals("null"))
{
// ...
}
1. null is a keyword in Java, "null" is just a string of text.
2. .equals() checks to see if two objects are equal according to the given method's definition of equality. Null checks should always be made using the == comparison operator, as it checks reference equality.
If a variable is null, you cannot dereference it.
That means you can not invoke methods on it.
So... The following if statement will throw a NullPointerException every time the first clause is true:
if (a == null && a.length() == 0)
In other words: if a is null, you CANNOT invoke the length method on a.

NullPointerException using HashMap

I am trying to filter this exception by checking whether the HashMap is Null using an if statement. If the HashMap is null then running a method which loads it with values however seems that the if statement is also giving an NullPointerException.
How can this be restructured?
sqldata is the Hashmap and it is being loaded elsewhere however there is a possibility that it might not have any values (as per design) in which case I am trying to check (if the HashMap is empty/null) and reload it using a code snippet below:
if (sqldata.isEmpty()||sqldata.equals(null)) {
sqldata = fileloader.dbhealthload();
}
sqldata.equals is running the method equals of sqldata. In the case that sqldata is null, it does not have any methods, so java does not find it and throws a NullPointerException. You should check it with ==:
if (sqldata == null || sqldata.isEmpty()) {
sqldata = fileloader.dbhealthload();
}
Null references have no methods. Thus, you can't test null with equals - instead, you should test it with the == operator.
Change your code to
if(sqldata == null || sqldata.isEmpty())
You should not check for null this way,
// Invokes method on null when sqldata is null. so, this shouldn't be done
if (sqldata.isEmpty()||sqldata.equals(null)) {
sqldata = fileloader.dbhealthload();
}
Instead you need to check for null like this
if(sqldata == null || sqldata.isEmpty()){
sqldata = fileloader.dbhealthload();
}
you should use:
if (sqldata == null || sqldata.isEmpty()) {
sqldata = fileloader.dbhealthload();
}
At first you should check whether sqldata is null or not . After that you should check the emptyness.
First you need to check whether sqldata is null or not then you can proceed to check whether HashMap is empty. Follow the given approach.
if (sqldata==null||sqldata.isEmpty())
{
sqldata = fileloader.dbhealthload();
}
if sqldata is null and using first sqldata.isEmpty() in if then it will throw NullPointerException.
The reason for null pointer exception might be that you HashMap is never instantiated. One way to correct this is to ensure that the HashMap is always instantiated and then restructuring the code in the following way:
if(!sqldata.isEmpty()) {
do operations ...
} else {
reload ...
}
It is recommended to use the above programming practice. However, if you do not want an enforced instantiation of the HashMap object, then you need to check that is it null or not and once you have checked that, you should proceed to check whether it is empty. The code in that case will be:
if(!(sqldata == null)) {
if(!sqldata.isEmpty()) {
do operations ...
}
} else {
reload or instantiate ...
then do operations ...
}
You may also write the other way around.
In Java null is not an object, just a void reference, so you shouldn't call .equals on variable that can be null. The only correct way is to compare it with reference comparison:
sqldata == null
Another thing is || is lazy, this means as soon as it finds first (from left to right) true value, it does not evaluate other operands. Hence a very common pattern:
sqldata == null || sqldata.isEmpty()
And you should use it. The operator && is lazy also, so things like:
sqldata != null && sqldata.doStuff()
are possible.
The same applies to any variable, for example String variable.
s == null || s.isEmpty()
When it comes to comparing strings with a literal another common pattern should be used:
"a value".equals( s )
It work's and is safe because:
in case s is null .equals can handle it, just nothing equals to null
"a value" is a string literal, so it is never null
As a guideline, don't compare strings the other way around:
s.equals("a value")
and don't use reference comparison:
s == "a value"
A string variable sometimes can point to the same object as the literal, but not always!
Generally NullPointerException throw when when you try to use a reference that points to no location in memory (null).Calling a method on a null reference or trying to access a field of a null reference will trigger a NullPointerExecption.
In your code you are try to calling method isEmpty() using null reference of you HashMap object.
Always check null before checking any other condition or accessing method using object reference.
For Example :
HashMap sqldata = new HashMap();
if(sqldata!=null && sqldata.isEmpty())
{
sqldata = fileloader.dbhealthload();
}

Comparison of two null objects from two different types

public void m1(Integer f) {
...
}
public void m1(Float f) {
...
}
public void main() {
m1(null); // error: the method m1(Integer) is ambiguous for the type Main
m1((Integer) null); // success
}
Given the above example, we can admit in some ways that null is typed. So why do the following lines print true? Sure o1 and o2 both have no value (i.e. null), but they aren't from the same type (Integer vs Float). I firstly thought false would have been printed.
Integer i = null;
Object o1 = (Object) i;
Float f = null;
Object o2 = (Object) f;
System.out.println(o1 == o2); // prints true
// in short:
System.out.println(((Object) ((Integer) null)) == ((Object) ((Float) null))); // prints true
All null values are untyped and are equal. You can pass it to different reference types but it makes no difference for comparison purposes.
It is not the null value which is typed but the reference to the null which can be typed.
A common question is what happens here
class A {
public static void hello() { System.out.println("Hello World"); }
public static void main(String... args) {
A a = null;
a.hello();
System.out.println("a is an A is " + (a instanceof A)); // prints false.
}
}
The compiler sees the type of a as an A so the static method is called. But the value referenced is null and untyped.
The only operations you can perform with null without causing a NullPointerException is to assign or pass it without examining it or comparing it with another reference.
BTW
In short: The compiler will select a method based on the type of the reference, at runtime the execution is based on the class of the object referenced. At runtime null is treated as any type or no type or you get a NullPointerException if you try to dereference it.
"==" in Java checks to see if it is the same instance rather than simply "are they equal?". There is no concept of multiple instances of null in Java. If you compare null to null, you will always receive true regardless of type.
The reason why you cannot then pass null as an argument to a method with the same name as another with different parameter types is because either method could be a candidate to be called without further type context. Rather than guess which one that might be, it correctly indicates an error.
see http://docs.oracle.com/javase/specs/jls/se7/html/jls-4.html#jls-4.1
null belongs to the "null type". The "null type" has only one value - the null.
The null type is a subtype of every reference type. Therefore we can do
Integer i = null;
(Integer)null
In another word, null is a valid value in every reference type.
(Think of a type as a set of values; the types of a value is the sets it belongs to; "subtype" means "subset". )
Given the above example, we can admit that null is NOT typed: when you call m1(null), compiler cannot determine the type of the actual parameter and cannot decide which method to invoke. All nulls are equal and not typed, and so (null==null)==true.
Null does not have a type, but a reference (to null or anything else) has a type. We can declare two reference variables with different types, but the null they refer to is the same thing in both cases:
Integer a = null;
Double b = null;
In your example,
m1((Integer) null);
the compiler uses the type of the reference it is passed to work out which overloaded method to call, not the type of the null value itself.
In your example it proves that the compiler cannot identity the type (of null) and decide which method to call. So you have to explicity give the type. Also null == null will be always true; no matter whatever cast you do it doesnt change or give null a type.This post has a long description on null.

Categories