为什么 int num = Integer.getInteger(“123”) 会抛出 NullPointerException?
以下代码抛出:NullPointerException
int num = Integer.getInteger("123");
我的编译器是否调用 null,因为它是静态的?这没有任何意义!getInteger
发生了什么事情?
以下代码抛出:NullPointerException
int num = Integer.getInteger("123");
我的编译器是否调用 null,因为它是静态的?这没有任何意义!getInteger
发生了什么事情?
这里有两个问题在起作用:
Integer getInteger(String)
不做你认为它做的事情null
Integer
int
Integer
null
NullPointerException
要解析为 ,您可以使用 例如 .(String) "123"
(int) 123
int Integer.parseInt(String)
Integer
接口引用Integer.getInteger
以下是文档对此方法的作用的看法:
公共静态 Integer getInteger(String nm):
确定具有指定名称的系统属性的整数值。如果没有具有指定名称的属性,如果指定的名称为空或 ,或者如果属性没有正确的数字格式,则返回。null
null
换句话说,此方法与将 a 解析为值无关,而是与 System.getProperty
方法有关。String
int/Integer
诚然,这可能是一个惊喜。不幸的是,该库有这样的惊喜,但它确实教会了你一个宝贵的教训:总是查找文档以确认方法的作用。
巧合的是,这个问题的变体出现在《拼图的回归:Schlock and Awe》(TS-5186)、Josh Bloch和Neal Gafter的2009年JavaOne技术会议演讲中。这是最后一张幻灯片:
道德
- 图书馆里潜伏着奇怪而可怕的方法
- 有些名字听起来无害
- 如果您的代码行为异常
- 确保调用的方法正确
- 阅读库文档
- 对于 API 设计人员
- 不要违反最小惊讶原则
- 不要违反抽象层次结构
- 不要对截然不同的行为使用相似的名称
为了完整起见,还有这些方法类似于:Integer.getInteger
当然,另一个问题是如何抛出。为了关注这个问题,我们可以简化代码段,如下所示:NullPointerException
Integer someInteger = null;
int num = someInteger; // throws NullPointerException!!!
以下是《有效 Java 第 2 版》第 49 项中的一段话:优先选择基元类型而不是盒装基元:
总之,只要您有选择,就应优先使用带框的基元。基元类型更简单、更快捷。如果必须使用盒装基元,请小心!自动装箱可减少使用装箱基元的详细程度,但不会减少危险。当您的程序将两个盒装基元与运算符进行比较时,它会进行标识比较,这几乎肯定不是您想要的。当您的程序执行涉及盒装和未装箱基元的混合类型计算时,它会取消装箱,而当您的程序执行拆箱时,它可以抛出 .最后,当您的程序框住基元值时,可能会导致昂贵且不必要的对象创建。
==
NullPointerException
有些地方你别无选择,只能使用盒装基元,例如泛型,但除此之外,你应该认真考虑使用盒装基元的决定是否合理。
从 http://konigsberg.blogspot.com/2008/04/integergetinteger-are-you-kidding-me.html:
getInteger “确定具有指定名称的系统属性的整数值。
你想要这个:
Integer.parseInt("123")