157

As you know, java.util.Objects is

This class consists of static utility methods for operating on objects.

One of such methods is Objects.isNull().

My understanding is that Objects.isNull() would remove the chance of accidentally assigning a null value to object by omitting the second =.

However, the API Note states:

This method exists to be used as a Predicate, filter(Objects::isNull)

Would there be any reason/circumstance for which I should use object == null over Objects.isNull() in an if statement?

Should Objects.isNull() be confined to Predicates exclusively?

Ivar
  • 6,138
  • 12
  • 49
  • 61
Lucas T
  • 3,011
  • 6
  • 29
  • 36
  • there`s also Objects.requireNonNull(T obj); btw – Marc Wittmann Jun 22 '16 at 15:53
  • 7
    If all you are worrying is accidental assignment, you can simply use `if(null == variable)` consistently… – Holger Jun 22 '16 at 16:36
  • 2
    @Holder, what accidental assignment is there to worry about? This is Java. You'll get a type error. – Louis Wasserman Jun 22 '16 at 17:35
  • 1
    @LouisWasserman Not if `variable` is a `Boolean`. – Alexis C. Jun 22 '16 at 18:27
  • 3
    @AlexisC, that'd be a concern in a _tiny, tiny_ number of cases: your variable has to be a very specific type, _and_ you have to make a very specific typo, _and_ you can't be using any IDE or compiler analysis that would point that out for you (as almost all IDEs would). I'm quite comfortable not worrying about that case. – Louis Wasserman Jun 22 '16 at 18:28
  • 2
    At work, I have seen many instances of **null==object**. When I enquired, I was told that it was to prevent accidental null assignments. Based on comments and answers here provided, I would be inclined to believe that it is a mater of taste. – Lucas T Jun 23 '16 at 13:50

5 Answers5

149

Objects.isNull is intended for use within Java 8 lambda filtering.

It's much easier and clearer to write:

.stream().filter(Objects::isNull) 

than to write:

.stream().filter(x -> x == null).  

Within an if statement, however, either will work. The use of == null is probably easier to read but in the end it will boil down to a style preference.

Glenn
  • 8,932
  • 2
  • 41
  • 54
Craig Taylor
  • 1,689
  • 1
  • 11
  • 13
  • 10
    I would disagree on the claim that it is "much easier/clearer to write". 1. It is not more concise. 2. It is obviously less expressive, especially for those not familiar with latest Java syntax. For me as someone who is not writing Java on daily basis (I write Scala) it feels hallucinatory having a static method which does nothing but checking for null. This method is just a distruction from fluent code reading without any benifits added. – Eli Golin Jan 10 '21 at 12:57
  • @EliGolin your phrasing gave me a good laugh – temporary_user_name Apr 18 '22 at 15:42
  • 1
    @EliGolin While I agree with your readability points, there is also a (very slight) performance benefit to not using Lambda expressions here. That is, the program won't have to define and instantiate a new anonymous method, both of which have (very slight) memory/compute overhead compared to just passing `isNull`. Slight as this overhead is, it adds up over all the Stream expressions in your codebase. For this reason alone, I always default to `isNull` syntax in Streams (_not_ in other contexts like if statements). – Rabadash8820 May 02 '23 at 19:08
  • Once the expression becomes even slightly more complex though, yes I would probably switch to a Lambda for readability. E.g., `.map(MyType::getProp).filter(Objects.isNull)` feels kinda awkward compared to just `.filter(x -> x.getProp() == nulll)`. Plus, I think the chained `map`/`filter` calls might actually be slower than the single `filter`. But again, we're talking about a super micro difference, and I've never actually benchmarked it. – Rabadash8820 May 02 '23 at 19:09
  • One of the tenants of streams usage I follow is to keep the individual operations within the stream and distinct. There may be a small time difference between the mapping and the filter however in the 80% (percentages may vary) of cases I'd argue for the added clarity. – Craig Taylor Aug 10 '23 at 13:56
144

should use object == null over Objects.isNull() in a if statement?

If you look at the source code of IsNull method,

 /* Returns true if the provided reference is null otherwise returns false.*/

 public static boolean isNull(Object obj) {
     return obj == null;
 }

It is the same. There is no difference. So you can use it safely.

syntagma
  • 23,346
  • 16
  • 78
  • 134
Suresh Atta
  • 120,458
  • 37
  • 198
  • 307
  • 21
    Yes, it can be used, but it may interfere with local flow analysis performed by a tool. I.e., with a plain "==", any flow analysis can see that dereference is not good in the then branch, but safe in an else branch. You'll get appropriate errors/warnings or nothing. With the indirection of calling isNull() that knowledge may be lost to the tool. – Stephan Herrmann Jun 25 '16 at 10:57
  • 5
    There IS a slight performance difference. Java checking for object null reference versus calling a static method will have a difference. And it reads slightly less clearly than just using == that we're all used to. – Kevin M Sep 27 '18 at 14:33
  • 11
    Is more semantic use `== null` in `if`, but isNull is great to use on lambda expressions. – Leonardo Ramos Duarte Nov 14 '18 at 10:09
  • 4
    it's surely legitimate, but does not have any benefits over the operators. So if you working in a team, please use things according to their intended purpose. – Alex Panchenko Dec 18 '19 at 06:22
16

Look at the source:

public static boolean isNull(Object obj) {
    return obj == null;
}

To check for null values, you can use:

  • Objects.isNull(myObject)
  • null == myObject // avoids assigning by typo
  • myObject == null // risk of typo

The fact that Objects.isNull is meant for Predicates does not prevent you from using it as above.

Mena
  • 47,782
  • 11
  • 87
  • 106
  • 1
    What do you mean by risk of typo? – Ashish Lohia Jul 12 '17 at 06:56
  • 3
    @AshishLohia by using `=` instead of `==` (wouldn't compile unless it's a nullable `Boolean` wrapper, yo be fair) – Mena Jul 12 '17 at 10:25
  • 15
    Risk of typo is the issue in C++ not in Java if (myObject = null) will result in the compilation error. You should always use myObject == null over null == myObject. – Tomas Marik Feb 23 '18 at 14:14
  • 1
    @TomasMarik as mentioned in my comment, the risk of typo is limited to nullable `Boolean` wrappers in Java. This is pretty rare indeed (and will give compiler warnings when an assignment to `null` is checked as if it were a condition), but not impossible. – Mena Feb 23 '18 at 14:29
  • null == myObject. This tricky way should be avoided; it goes against our natural language when comparing something by reading from left to right. – emeraldhieu Sep 08 '22 at 08:20
  • 1
    @emeraldhieu the term for such expression is `yoda conditions` which go against natural language and yes, should be avoided. – shazwashere Sep 21 '22 at 15:57
  • @shazwashere Hah! Thanks for the term! It's useful for me to show other devs in code review. – emeraldhieu Sep 23 '22 at 14:56
11

Would there be any reason/circumstance for which I should use object == null over Objects.isNull() in a if statement?

Yes, one reason is to keep the code simple. Within if statement object == null is clear and well known. It can not lead to any misbehavior if for example there is a typo.

My understanding is that Objects.isNull() would remove the chance of accidentally assigning a null value to object by omitting the second =.

If there is an if (object = null) {} with omitted = it will not compile or it will generate warning in case of Boolean object! Actually there is no reason to use Objects.isNull(object) over object == null within if statement. Here are the two variants side by side:

if (object == null) {
}

if (Objects.isNull(object)) {
}

Should Objects.isNull() be confined to Predicates exclusively?

It could be said yes, it is confined to Predicates exclusively, although there is no technical hurdle to use the Objects.isNull() everywhere.

From the public static boolean isNull(Object obj) method's javadoc:

@apiNoteThis method exists to be used as a java.util.function.Predicate, filter(Objects::isNull)

So if you use the method as not a predicate you are actually using a more complex and cumbersome expression compared to the simple object == null.

Here is a snippet to compare the benefit of Objects.isNull(object)

List<String> list = Arrays.asList("a", "b", null, "c", null);

// As ready-made predicate
long countNullsWithPredicate = list.stream().filter(Objects::isNull).count();

// Lambda
long countNullsWithLambda = list.stream().filter(object -> object == null).count();

// Reimplement the Objects::isNull predicate
long countNullsWithAnonymous = list.stream().filter(new Predicate<Object>() {
    @Override
    public boolean test(Object obj) {
        return obj == null;
    }
}).count();
Vasil
  • 313
  • 1
  • 3
  • 7
6

Semantically there is no difference but for readability I prefer the following over whatever == null:

import static java.util.Objects.isNull;

// Other stuff...

if(isNull(whatever)) { 

}
  • Do you know if there is a difference in performance? Someone told me calling the method will result in wasted cpu cycles. – Slaknation Mar 03 '22 at 18:06
  • Inside there's regular == null comparison, so you will need to put some extra frames on stack to make that call. However it shouldn't make a difference in real world app. If that someone claims otherwise then he/she should be avoided. If it's your tech lead, you should consider switching job. – Somal Somalski Mar 17 '22 at 14:01