8

Given the following:

Integer var1 = null;
Integer var2 = 4;
Integer result = var1 + var2; // throws NullPointerException

The requirement for my use case is that result should be null whenever either operand is null (and the same applies for other operators). I know I can use an if statement to do this but is there a smarter way?

Steve Chambers
  • 37,270
  • 24
  • 156
  • 208
  • I got the same NPE, we have to bear in mind that arithmetic operations are done in primitive types, and always take class types unbox npe in to considoration. – keke2048 Apr 21 '17 at 07:59

6 Answers6

9

The best way is not to use Boxed types for normal arithmetic operations. Use primitive types instead.

Only if you are using them in the collections somewhere you should resort to Boxed types.

EDIT:

Incorporating the suggestion from @Ingo there is a good utility class Optional in Guava, which explains on how to avoid nulls.

Now use of this class makes it explicit that the value can be null.

Narendra Pathai
  • 41,187
  • 18
  • 82
  • 120
5
Integer var1 = null;
Integer var2 = 4;
Integer result = (var1 == null || var2 == null) ? null : var1 + var2; // returns null if either argument is null
stackular
  • 1,431
  • 1
  • 19
  • 41
  • Thanks, am aware I can do this but it will be used multiple times throughout the code. OK, could create methods to do it for all the different operators but this seems like it must be reinventing a wheel... – Steve Chambers Nov 21 '13 at 09:40
  • You have to do `null` checking yourself every time, but this simple comparison is one of the fastest features of most CPUs. – stackular Nov 21 '13 at 09:45
  • It's not really speed that bothers me so much as the extra code. Java works differently to SQL where `1 + NULL = NULL` - had hoped there'd be some way of making this behaviour using the API but it seems not... – Steve Chambers Nov 21 '13 at 10:36
  • 1
    The problem with `null` in SQL is that it adds a lot of unneeded complexity and makes some code behaviors difficult to predict. It is better to get a NPE than to have your code behave in unexpected ways. Further reading: https://en.wikipedia.org/wiki/Null_(SQL)#Controversy – stackular Nov 21 '13 at 11:17
2

Unfortunately no, there is no other way in Java to prevent NullPointerException on boxed types other than to explicitly check for null.

The same applies to .equals(), you can do:

Integer var1 = null;
Integer var2 = 4;
var1 == var2

But if you want to compare values:

Integer var1 = null;
Integer var2 = 4;
var1.equals(var2)  //throws NullPointerException

This is why a two argument static Object::equals (see here) was introduced in 2011 to Java.

There are no such methods for boxed numbers (like Integer). In fact during var1 + var2 you get automatic unboxing which causes exception. So you are not adding two Integers, but .intValue() is called instead on both of them, and then a new Integer is constructed from the result.

See this Stack Overflow answer for further information on boxed numbers: Unboxing Long in java.

Sorry, this is one of the Java's nuisance. If you work on Integers, check for null every time.

Community
  • 1
  • 1
user2622016
  • 6,060
  • 3
  • 32
  • 53
0

int and Integer has its own properties and they are used for specified functions.

int is a primitive datatype and its not considered as an object. ie; the values in an int can only be from a predefined set of elements.

Integer are wrapped in an object so they have the behaviour of an object.

So if you want to have use just the arithmetic operations , you better use int instead of Integer.

When you are using the Integer for arithmetic operation , it UnBox the Integer to find the int value and then do the operations and get it boxed. so the overhead is more and hence its a bad practice.

Dileep
  • 5,362
  • 3
  • 22
  • 38
0

Technically, this doesn't have an if per se:

Integer result = var1 == null || var2 == null ? null : var1 + var2;

You could refactor this into a utility method for reuse:

public static Integer add(Integer var1, Integer var2) {
    return var1 == null || var2 == null ? null : var1 + var2;
}
Bohemian
  • 412,405
  • 93
  • 575
  • 722
  • I know it doesn't but that's not really the point - this is just syntactic sugar for the same thing and would still need to be repeated in multiple places. – Steve Chambers Nov 21 '13 at 10:37
  • @SteveChambers I did add the "technicality" disclaimer :) I added a utility method just for you. – Bohemian Nov 21 '13 at 12:29
  • Yep, agree I could add those methods (including `subtract`, `multiply`, `divide`, `modulus` etc. for `Integer`, `Long`, `Float` etc.) but this does feel like something that could easily have been provided in the core Java API - am presuming there was some good reason they weren't... – Steve Chambers Nov 21 '13 at 13:54
  • 1
    @SteveChambers it's a language design choice - java has few "default" behaviours in order to give high predictability. SQL handles nulls in the way OP would like – Bohemian Nov 21 '13 at 20:24
-1

I guess you could catch it instead of using if :

Integer result = null;
try {
  result = var1 + var2;
} catch(NullPointerException ex) {}

The good news is, you don't have to test the values of var1 or var2, and the value is already null by default (so you don't need setting it in the catch block).

Pierre Arlaud
  • 4,040
  • 3
  • 28
  • 42
  • 3
    You really should use `if` instead of `try..catch` whenever possible. Exceptions are much more expensive than simple conditional statements. – stackular Nov 21 '13 at 09:36
  • True. But he asked for "a smarter" way, and my interpretation of smart isn't necessarily "less costy". – Pierre Arlaud Nov 21 '13 at 09:37