1

I am working on sprint boot application, and I am working on SonarQube blocker resolving an issue.

So I get one issue to be resolved:

Ensure this "Optional" could never be null and remove this null-check.

So I have changed the condition from

myObj != null -> Optional.ofNullable(myObj).isPresent()

I can't use myObj.isPresent() directly as myObj can be null, so it will throw null pointers.

Now I'm stacked in one situation when myObj is empty as

myObj= Optional.empty();
Optional.ofNullable(myObj).isPresent(); // True
myObj.isPresent(); // False;

So as I have mentioned I have changed my condition checking myObj!=null with Optional.ofNullable(myObj).isPresent(), it will work fine for null object and if object is empty then it will be true for empty object and when I access get() on object then it'll throw : No value present

How can I avoid null and empty together in one condition?

I don't want to add && condition to check for non-empty of myObj as :

Optional.ofNullable(myObj).isPresent() && !myObj.isEmpty()

Can I check this with single statement for null as well for empty or vice-versa?

Alexander Ivanchenko
  • 25,667
  • 5
  • 22
  • 46
Neelam Sharma
  • 2,745
  • 4
  • 32
  • 73

1 Answers1

2

Optional type, it was introduces in JDK for only one particular purpose - to be used as a return type when return well could potentially be null. Any other cases when optional is utilized just in order to chain on it, or as a type of parameter or field isn't considered to be a good practice.

You definitely shouldn't wrap the Optional object with another Optional.

The fact that you have an optional that could be null itself isn't a good indicator. It must not happen in the first place. Because of that you hardly can come up with a clean and elegant solution.

Accessing the value isn't the actual problem, the problem is you optional could potentially be null. It shouldn't be the case, you must not return null instead of optional. That's the rule of thumb.

You could use either of these, but bear in mind that it doesn't eliminate the problem, rather disguises it:

if (Stream.ofNullable(myObj).anyMatch(Optional::isPresent)) {
    something = myObj.get();
}
something = Stream
        .ofNullable(myObj)
        .filter(Optional::isPresent)
        .findFirst().orElse(defaultValue);

Your issue is stated as:

Ensure this "Optional" could never be null and remove this null-check.

As I understand this, you have to address the root of the problem: find out from where null optionals are coming from and replace null with an empty optional.

Alexander Ivanchenko
  • 25,667
  • 5
  • 22
  • 46
  • Thanks for the answer, but I can not change existing code that is using Option for each variable created. I need solution for empty and null to be check. with Optional in one. – Neelam Sharma Mar 25 '22 at 11:41
  • @NeelamSharma The condition above doesn't require any changes. It'll work only if `myObj` is an optional. – Alexander Ivanchenko Mar 25 '22 at 11:47
  • @NeelamSharma In order to utilize effectively optional object, it must be either empty or contain a value. Optional isn't designed to be `null`, conversely it's meant to avoid `null` values. In the station you have, you need to use a condition that checks that object is not `null`. – Alexander Ivanchenko Mar 25 '22 at 11:59
  • 3
    `Objects.nonNull(myObj)` is just a `myObj != null` in disguise. It’s not improving anything. As [the documentation](https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/util/Objects.html#nonNull(java.lang.Object)) states, the purpose of this method is to support `Object::nonNull` predicates, not to replace every null-check of an application. – Holger Mar 25 '22 at 12:17
  • @Holger My bad, I've messed the things. Amended – Alexander Ivanchenko Mar 25 '22 at 12:27