简体   繁体   English

如何避免来自 Java 算术运算符的 NullPointerException?

[英]How to avoid NullPointerException from arithmetic operators in Java?

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).我用例的要求是, result应该是null ,只要有一个操作数为null (这同样适用于其他运营商)。 I know I can use an if statement to do this but is there a smarter way?我知道我可以使用if语句来做到这一点,但有没有更聪明的方法?

The best way is not to use Boxed types for normal arithmetic operations.最好的方法是不要将Boxed 类型用于正常的算术运算。 Use primitive types instead.改用原始类型。

Only if you are using them in the collections somewhere you should resort to Boxed types.只有当你在某个地方的集合中使用它们时,你才应该求助于 Boxed 类型。

EDIT:编辑:

Incorporating the suggestion from @Ingo there is a good utility class Optional in Guava, which explains on how to avoid nulls.结合@Ingo 的建议,Guava 中有一个很好的实用程序类Optional ,它解释了如何避免空值。

Now use of this class makes it explicit that the value can be null .现在使用这个类可以明确表示该值可以为null

Integer var1 = null;
Integer var2 = 4;
Integer result = (var1 == null || var2 == null) ? null : var1 + var2; // returns null if either argument is null

Unfortunately no, there is no other way in Java to prevent NullPointerException on boxed types other than to explicitly check for null .不幸的是,除了显式检查null之外,Java 中没有其他方法可以防止盒装类型的NullPointerException

The same applies to .equals() , you can do:这同样适用于.equals() ,你可以这样做:

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.这就是为什么在 2011 年向 Java 引入了两个参数的静态Object::equals (参见此处)。

There are no such methods for boxed numbers (like Integer ).盒装数字没有这样的方法(如Integer )。 In fact during var1 + var2 you get automatic unboxing which causes exception.实际上,在var1 + var2期间,您会自动取消装箱,从而导致异常。 So you are not adding two Integer s, but .intValue() is called instead on both of them, and then a new Integer is constructed from the result.所以你没有添加两个Integer s,而是在它们两个上调用.intValue() ,然后根据结果构造一个新的 Integer 。

See this Stack Overflow answer for further information on boxed numbers: Unboxing Long in java .有关盒装数字的更多信息,请参阅此 Stack Overflow 答案: Unboxing Long in java

Sorry, this is one of the Java's nuisance.抱歉,这是Java 的麻烦之一。 If you work on Integer s, check for null every time.如果您在Integer工作,请每次检查null

I guess you could catch it instead of using if :我想你可以抓住它而不是使用 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).好消息是,您不必测试 var1 或 var2 的值,并且默认情况下该值已经为空(因此您不需要在 catch 块中设置它)。

int and Integer has its own properties and they are used for specified functions. intInteger有自己的属性,它们用于指定的功能。

int is a primitive datatype and its not considered as an object. int是一种原始数据类型,它不被视为对象。 ie;即; the values in an int can only be from a predefined set of elements. int 中的值只能来自一组预定义的元素。

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.因此,如果您只想使用算术运算,最好使用 int 而不是 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.当您使用Integer进行算术运算时,它 UnBox Integer以找到int值,然后执行操作并将其装箱。 so the overhead is more and hence its a bad practice.所以开销更多,因此这是一种不好的做法。

Technically, this doesn't have an if per se:从技术上讲,这本身没有if

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;
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM