java.util.Objects.isNull vs object == null - java

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?

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.

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.

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.

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();

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)) {
}

Related

Nested if-object-null-return method extraction or alternative for sonar cognitive complexity

In most cases when an object is optional, it is possible to use Guava to help in if null checks. But in cases where the statement is used to decide if the method is going to return earlier (from what I experienced) even that is not enough.
My question regards the use of nested if-statements to return a default value instead of continuing with the method execution.
Here's an example of what I mean:
private MyObject myMethod(Object object, Object object1, Object object2) {
/* inherent implementations for first if-statement... */
if (object == null) {
/* inherent implementations for second if-statement... */
if (object1 == null) {
return new MyObject();
}
/* inherent implementations for third if-statement... */
if (object2 == null) {
return new MyObject();
}
} else {
/*same structure shown in if-statement...*/
}
/* inherent implementations before last return statement... */
return new MyObject(/* with args */);
}
I am looking for a solution that solves the problems of cognitive complexity indicated sonarQube in which the amount of 'if' and nested 'if' statements used in the method increments the complexity of the code.
In other words, ways to extract the statements from the method into another method or solving them through other ways that don't involve if-statements.
EDIT(05/09): First, thanks for all of the answers provided, but I believe there's a bit of a detail I forgot to mention. Each of the /* implementations... */ that are mentioned in the code snippet I provided have some type of functionality that must be fulfilled before the next if-statement so suggestions like if (object1 == null || object2 == null) are a no-go. About the suggestion of using Java 9's Optional.or: from what I heard, Java 8 is the currently most stable version of Java so worst case scenario I would wind up having to wait for Java 11. Also each of the /* implementations... */ mentioned have to be executed in in order, so in order to make each of those details more explicit I have reworked a bit of the code snippet I provided earlier.
The answers from clean code perspective:
Don't go with so many arguments. It sounds silly first, but: the real answer is to design interfaces that take as few parameters as possible. So, instead of passing a, b, c as parameters one could create a class around them. Which gives you more options to think about default values, and so on.
Of course, early returns are possible as well.
Your code says same structure as shown in if statement. Then the simple solution is to do
if (object1 == null) return new MyObject();
if (object2 == null) return new MyObject();
once, before any other code. The point is to avoid the nesting of conditions. And when you just repeat conditions, then put them in a different place and avoid the repetition.
To check if some of your parameters are null you can create a method like that :
public boolean hasNull(Object... objects) {
return Arrays.stream(objects).anyMatch(Objects::isNull);
}
Now you can check as much as parameters you want :
private MyObject myMethod(Object object, Object object1, Object object2, Object object3, Object object4) {
if (hasNull(object1, object2, object3, object4)) {
return new MyObject();
}
/* implementations... */
return new MyObject(/* with args */);
}

Java ArrayList contains method

#Override
public boolean contains(Object object) {
if (object != null) {
for (E element : a) {
if (object.equals(element)) {
return true;
}
}
} else {
for (E element : a) {
if (element == null) {
return true;
}
}
}
return false;
}
I am learning java and I am looking into the source code to find out how certain methods are being written. I would like to ask why is there a need to write
else {
for (E element : a) {
if (element == null) {
return true;
}
}
}
Thank you
Yes there is.
If object is null, object.equals(element) will throw a NullPointerException
So the case where object is null is handled in a separate loop.
Input argument can be null or not null.
If it's null then we need to iterate through all list elements and return true if there is null in the array.
And we have to use == operator, because equals will throw NullPointerException.
I would like to ask why is there a need to write
else {
[...]
Because otherwise, the method would always return false in the event that the condition of the if statement (object != null) is not satisfied, but that is inconsistent with the method's contract / documentation. Many Java List implementation can contain the value null as an element, and when they do, contains(null) must return true for them.
That is handled in a separate branch because when object is null, any attempt to invoke a method on it, such as equals() will cause a NullPointerException to be thrown. The approach in the if block therefore cannot be applied in that case.
List is a collection that allows insertion of null referenced objects into it.
the algorithm meant to tell you that if you have at least null in the list and you ask/search a null object later then it will return true at the 1st match....
because .equals() comparison method cannot be invoked on null and if you would invoke then null.equals(SOMETHING); will throw a NullPointerException. So here old traditional way comes to the rescue! use == comparison operator.
Many methods in Collections Framework interfaces are defined in terms of the equals method. For example, the specification for the contains(Object o) method says: "returns true if and only if this collection contains at least one element e such that (o==null ? e==null : o.equals(e))." This specification should not be construed to imply that invoking Collection.contains with a non-null argument o will cause o.equals(e) to be invoked for any element e. Implementations are free to implement optimizations whereby the equals invocation is avoided, for example, by first comparing the hash codes of the two elements. (The Object.hashCode() specification guarantees that two objects with unequal hash codes cannot be equal.) More generally, implementations of the various Collections Framework interfaces are free to take advantage of the specified behavior of underlying Object methods wherever the implementor deems it appropriate.
Refer:https://docs.oracle.com/javase/7/docs/api/java/util/Collection.html
There is a need to write else { ... because the if condition holds true only if the arg 'object' is not null.
In this case your contains() method implemented to check if object value is null or not, if it is null return true otherwise false. Implementing this method give you a opportunity to check any object(passing object as a parameter) value(using if condition or any other condition). Later on when you want to check values is there or not if it is have value you can do manipulation on object.
In ArrayList contains():
The ArrayList.contains(Object) method returns true if this list contains the specified element.
ArrayList<Integer> listObj = new ArrayList<Integer>();
listObj.add(1);
listObj.add(2);
System.out.println("Contains : "+listObj.contains(1));
This method more important check element and do somework if it is true. As a example,
if(listObj.contains(2)){
int index=arrlist.indexOf(2);
listObj.remove(index);
}
What is happening here is that the value(object) pass as the parameter is not a null value,
public boolean contains(Object object) {
if (object != null) {
then go through the ArrayList element,
for (E element : a) {
is equal to pass value,
if (object.equals(element)) {
return true
Otherwise(if object is null) go with the else block.
Throws:
ClassCastException - if the type of the specified element is incompatible with this list.
NullPointerException - if the specified element is null and this list does not permit null elements.
read more
Let's say object is a String:
This contains() method also in String class. Little bit different scenario but concept is same.
when you wish to check if one String contains a specific substring.
String word= "Hey there how are you";
if(word.contains("you")){
System.out.println("I am fine!");
}

Compare object type

I don't know how to perform type checking on newEntry, I want to make sure that it is of type MyTable (without creating an object of MyTable).
public static boolean add(String table, Object newEntry)
{
boolean result;
if (table.equals("MyTable") && newEntry.getClass() == MyTable.getClass())
{
...
}
}
My problem is:
newEntry.getClass() == MyTable.getClass().
Note: MyTable is a class name, not an object.
Basically what you want is:
isAssignableFrom
Take a look at: http://www.ralfebert.de/blog/java/isassignablefrom/
So, in your case, you want:
MyTable.class.isAssignableFrom(newEntry.getClass())
Use instanceof operator .. Refer to the JLS for more documentation
Check this famous answer What is the difference between instanceof and Class.isAssignableFrom(...)?
instanceof is your friend:
if (table.equals("MyTable") && newEntry instanceof MyTable)
It is actually a shorthand for the isAssignableFrom method, but it's much easier to type :)
Compare with instanceof.
if (newEntry instanceof MyTable) {
// do something
}
In this example, the condition is true if newEntry is an instance of MyTable, or if newEntry is an instance of a superclass of MyTable.
Change your statement to this to make it work properly:
if (table.equals("MyTable") && newEntry instanceof MyTable)
You could also use isAssignableFrom() to compare them. The reason you might want to do this is because with instanceof, you have to know the class you are comparing before you compile your program. With isAssignableFrom(), you can change the class you are comparing to during run-time.
if (table.equals("MyTable") && MyTable.class.isAssignableFrom(newEntry.getClass()))
You can use MyTable.class to retrieve the class name.

Does java.util.List.isEmpty() check if the list itself is null? [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 5 years ago.
Does java.util.List.isEmpty() check if the list itself is null, or do I have to do this check myself?
For example:
List<String> test = null;
if (!test.isEmpty()) {
for (String o : test) {
// do stuff here
}
}
Will this throw a NullPointerException because test is null?
You're trying to call the isEmpty() method on a null reference (as List test = null;). This will surely throw a NullPointerException. You should do if(test!=null) instead (checking for null first).
The method isEmpty() returns true, if an ArrayList object contains no elements; false otherwise (for that the List must first be instantiated that is in your case is null).
You may want to see this question.
I would recommend using Apache Commons Collections:
https://commons.apache.org/proper/commons-collections/apidocs/org/apache/commons/collections4/CollectionUtils.html#isEmpty-java.util.Collection-
which implements it quite ok and well documented:
/**
* Null-safe check if the specified collection is empty.
* <p>
* Null returns true.
*
* #param coll the collection to check, may be null
* #return true if empty or null
* #since Commons Collections 3.2
*/
public static boolean isEmpty(Collection coll) {
return (coll == null || coll.isEmpty());
}
No, java.util.List.isEmpty() doesn't check if a list is null.
If you are using the Spring framework you can use the CollectionUtils class to check if a list is empty or not. It also takes care of the null references. Following is the code snippet from Spring framework's CollectionUtils class.
public static boolean isEmpty(Collection<?> collection) {
return (collection == null || collection.isEmpty());
}
Even if you are not using Spring, you can go on and tweak this code to add in your AppUtil class.
This will throw a NullPointerException - as will any attempt to invoke an instance method on a null reference - but in cases like this you should make an explicit check against null:
if ((test != null) && !test.isEmpty())
This is much better, and clearer, than propagating an Exception.
Invoking any method on any null reference will always result in an exception. Test if the object is null first:
List<Object> test = null;
if (test != null && !test.isEmpty()) {
// ...
}
Alternatively, write a method to encapsulate this logic:
public static <T> boolean IsNullOrEmpty(Collection<T> list) {
return list == null || list.isEmpty();
}
Then you can do:
List<Object> test = null;
if (!IsNullOrEmpty(test)) {
// ...
}
In addition to Lion's answer, I can say that you better use if(CollectionUtils.isNotEmpty(test)){...}.
This also checks for null, so a manual check is not needed.
Yes, it will throw an Exception. Maybe you are used to PHP code, where empty($element) does also check for isset($element). In Java this is not the case.
You can memorize that easily, because the method is directly called on the list (the method belongs to the list). So if there is no list, then there is no method. And Java will complain that there is no list to call this method on.
You can use your own isEmpty (for multiple collection) method too. Add this to your Util class.
public static boolean isEmpty(Collection... collections) {
for (Collection collection : collections) {
if (null == collection || collection.isEmpty())
return true;
}
return false;
}

Standard approach to assign default value in Java

Often I invoke alien methods which might return a null value. In order to avoid simple null checks like
if (myVariable != null) {
// do something
}
I sometimes assign a default value, like this:
myVariable = (myVariable == null) ? defaultValue : myVariable;
This seems a little bit redundant in Ruby for instance, there is the ||= operator
I am not asking for such an operator, but my standard approach with the ternary operator seems a little bit redundant or maybe also confusing?
What better ways are there?
Try this:
if (myVariable == null) {
myVariable = defaultValue;
}
If the alien method maybe return null value, it should note about null return value in method's Java docs. The client uses that alien method must check, but no way, the return value.
The simple way to do this:
retVal = alienMethod();
if (retVal == null) {
retVal = defaultVal;
}
If you still want to avoid checking null value, the method that return the value must be in responsible for return default value. But what is your default value? Depend on your return type, you can create a dummy class to represent your default value instead of returning null value.
There are no better/shorter/nicer ways to do it....
There was talk about introducing a '?' operator for null values in Java 7, but the concept got shifted out of the release.... maybe for Java 8 ?
https://blogs.oracle.com/darcy/entry/project_coin_final_five
http://viralpatel.net/blogs/2009/10/null-safe-type-java-7-nullpointerexception.html
http://mail.openjdk.java.net/pipermail/coin-dev/2009-March/000047.html
In general, there is no "elegant" way. If the variable is a field of your class, you can do it in the setter or getter. But proper javadocs (which I don't show below!) are important to explain what happens to nulls. e.g.
public void setFoo(Foo foo) {
this.foo = foo != null ? foo : DEFAULT_FOO;
}
public Foo getFoo() {
return foo != null ? foo : DEFAULT_FOO;
}
You can wrap the assigning of a default value into a small utility function and put it in a helper class. For variables of type String, this would look like this:
public static String unNull(String val,String defVal) {
return (val==null ? defVal : val);
}
Then, in your code you can just write
myVariable = unNull(alienMethod(),defaultValue);
Using a static import, you can do without prefixing the static method's name with the class name.
You can also make a generic method to handle this (to template the type of both arguments and the return type), but I'm not sure it would work without an additional parameter of type Class.
There is finally a better way to do it: Optional in Java 8. Instead of
Foo myVariable = bar();
myVariable = (myVariable == null) ? defaultValue : myVariable;
where bar() may return null, now you do
Foo myVariable = Optional.ofNullable(bar()).orElse(defaultValue).get()

Categories

Resources