陷阱 - 不必要地使用原始包装可能导致 NullPointerExceptions
有时,新 Java 的程序员将交替使用原始类型和包装器。这可能会导致问题。考虑这个例子:
public class MyRecord {
public int a, b;
public Integer c, d;
}
...
MyRecord record = new MyRecord();
record.a = 1; // OK
record.b = record.b + 1; // OK
record.c = 1; // OK
record.d = record.d + 1; // throws a NullPointerException
我们的 MyRecord
类 1 依赖于默认初始化来初始化其字段上的值。因此,当我们记录时,a
和 b
字段将被设置为零,c
和 d
字段将被设置为 null
。
当我们尝试使用默认的初始化字段时,我们看到 int
字段始终有效,但 Integer
字段在某些情况下有效,而在其他情况下无效。具体来说,在失败的情况下(使用 d
),会发生的情况是右侧的表达式尝试取消打开 null
引用,这就是导致 NullPointerException
被抛出的原因。
有几种方法可以看看这个:
-
如果字段
c
和d
需要是原始包装器,那么要么我们不应该依赖于默认初始化,要么我们应该测试null
。前者是正确的方法,除非对于null
状态的字段有明确的含义。 -
如果字段不需要是原始包装器,那么使它们成为原始包装器是错误的。除了这个问题,原始包装器相对于原始类型还有额外的开销。
这里的教训是不使用原始包装类型,除非你真的需要。
1 - 本类不是良好编码实践的一个例子。例如,精心设计的类不会有公共字段。但是,这不是这个例子的重点。