Search code examples
javanullpointerexceptionprimitiveautoboxing

How to safely handle Java's wrapped primitives


I'm writing a program which needs to handle objects with many wrapped number variables such as Long, Double, Integer etc. How can I safely perform numeric operations on these without having to put null-checks everywhere?

I expect this is something that pretty much every Java programmer must deal with sooner or later, so I'm quite surprised that there aren't hundreds of blog posts and SO questions on the topic.

My current solution is to filter all the numbers trough a method like this:

private static safelyUnbox(Integer i) {
    return i == null ? 0 : i.intValue();
}
...
sumVariable += safelyUnbox(stupidObject.getNumberOfWhatever());

Solution

  • Java 8 provides a good alternative to checking against null. If an Integer (for example) might or might not have a value then you can declare it as Optional<Integer>. The Optional class has plenty of useful utilities for returning default values, throwing exceptions, checking if the value is present etc.

    The advantage of declaring Optional<Integer> is that you are making completely clear to the reader that 'no value' is a legitimate state. Anyone maintaining your code has no choice but to use the Optional methods to decide what happens if the value is present or absent.

    If, on the other hand, the argument is mandatory then the simplest option is to just assert that it is not null before using it.

    The great advantage (in my view) of using Optional whenever a value might not be present is that you can start relying in your code on the assumption that null is always an error.

    Optional even provides a neat way of converting a potentially null variable to an Optional (for example, if it's passed to you and you have no control over its value on entry to your code). It works like this:

    Optional<Integer> optVal = Optional.ofNullable(val);
    

    You can then use the new variable in the same way as any other Optional. For example:

    optVal.ifPresent(myList::add);
    

    Or:

    return optVal.orElse(27);