为什么int num = Integer.getInteger(“ 123”)抛出NullPointerException?


Answers:


212

大图景

这里有两个问题:

  • Integer getInteger(String) 不按照你的想法去做
    • null在这种情况下返回
  • Integer到的分配int会导致自动取消装箱
    • 由于Integeris nullNullPointerException被抛出

要解析(String) "123"(int) 123,您可以使用例如int Integer.parseInt(String)

参考文献

Integer API参考


Integer.getInteger

关于此方法的功能,文档说明如下:

public static Integer getInteger(String nm):确定具有指定名称的系统属性的整数值。如果没有具有指定名称null的属性,或者指定的名称为空或,或者该属性的格式不正确,则null返回该属性。

换句话说,此方法与将a解析Stringint/Integer值无关,而与System.getProperty方法有关。

诚然,这可能是一个惊喜。不幸的是,库有这样的惊喜,但是它确实教给您一个宝贵的教训:请始终查阅文档以确认方法的作用。

巧合的是,《难题的归来:施洛克和敬畏(TS-5186)》,乔什·布洛赫 Josh Bloch)和尼尔·戈夫特(Neal Gafter)在2009年JavaOne技术会议的演讲中介绍了此问题的变体。这是结论幻灯片:

道德

  • 库中潜伏着奇怪而可怕的方法
    • 有些名字听起来无害
  • 如果您的代码行为不当
    • 确保调用正确的方法
    • 阅读图书馆文件
  • 对于API设计人员
    • 不要违反最小惊讶原则
    • 不要违反抽象层次结构
    • 不要将相似的名称用于行为截然不同的行为

为了完整起见,还有这些方法类似于Integer.getInteger

相关问题


在自动拆箱中

当然,另一个问题是如何NullPointerException抛出。为了解决这个问题,我们可以按以下方式简化代码段:

Integer someInteger = null;
int num = someInteger; // throws NullPointerException!!!

这是来自Effective Java 2nd Edition,项目49的引用:优先于基元类型而不是盒装基元:

总之,只要有选择,就优先于框式基元使用基元。基本类型更简单,更快速。如果必须使用盒装原语,请当心!自动装箱减少了使用装箱原语的冗长程度,但没有危险。当您的程序将两个装箱的原语与==运算符进行比较时,它将进行身份比较,这几乎肯定不是您想要的。当您的程序进行涉及装箱和拆箱原语的混合类型计算时,它会进行拆箱,而当您的程序进行拆箱时,它会抛出NullPointerException。最后,当您的程序将原始值装箱时,可能会导致创建昂贵且不必要的对象。

在有些地方您别无选择,只能使用盒装基元,例如泛型,但是否则您应该认真考虑是否有理由使用盒装基元的决定。

相关问题


11
那么Integer.getInteger(s)大致相当于Integer.parseInt(System.getProperty(s))什么?我想我更喜欢第二个,尽管它比较冗长,因为它突出了您要从系统属性中提取信息的事实。
MatrixFrog 2010年

5
张贴评论后,我意识到我可以看看Integer类的实际来源!我在正确的轨道上,只是它使用Integer.decode代替代替Integer.parseInt,后者分别寻找前导0x0将数字解析为十六进制或八进制。
MatrixFrog 2010年

对于那些问为什么NullPointerExceptionprogrammers.stackexchange.com/questions/158908/…–
ROMANIA_engineer

2
@Oracle您可以弃用java.lang.Integer.getInteger(String)吗?
mjaggard


6

请检查方法getInteger()的文档。在此方法中,String参数是系统属性,该属性确定具有指定名称的系统属性的整数值。“123”是没有任何系统属性的名称,如讨论在这里。如果要将此String转换为int,则使用方法为 int num = Integer.parseInt("123")

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.