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

以下代码引发NullPointerException

 int num = Integer.getInteger("123"); 

我的编译器调用getInteger为null,因为它是静态的吗? 这没有任何意义!

发生了什么?

大的图片

这里有两个问题:

  • Integer getInteger(String)不会做你认为它
    • 在这种情况下它返回null
  • Integerint的赋值会导致自动拆箱
    • 由于Integernull ,所以抛出NullPointerException

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

参考

  • Java语言指南/自动装箱

Integer API参考

  • static int parseInt(String)
  • static Integer getInteger(String)

Integer.getInteger

以下是文档必须说明的方法:

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

换句话说,这个方法与将一个Stringparsing为一个int/Integer值无关,而是与System.getProperty方法有关。

无可否认,这可能是一个惊喜。 不幸的是,图书馆有这样的惊喜,但它确实教你一个宝贵的教训:总是查阅文件,以确认一种方法。

在“困惑的回归:Schlock and Awe”(TS-5186) ,Josh Bloch和Neal Gafter的2009年JavaOne技术会议演讲中,我们巧妙地发现了这个问题的一个变种。 这是最后的幻灯片:

道德

  • 奇怪和可怕的方法潜伏在图书馆
    • 一些有着无伤大雅的名字
  • 如果你的代码行为不当
    • 确保你正在调用正确的方法
    • 阅读库文档
  • 对于APIdevise者
    • 不要违反最小的原则
    • 不要违反抽象层次结构
    • 不要将类似的名字用于非常不同的行为

为了完整性,也有类似于Integer.getInteger

  • Boolean.getBoolean(String)
  • Long.getLong(String)

相关问题

  • 最惊人的违反最小的原则
  • Java Base API中最令人尴尬/误导的方法是什么?

在autounboxing

另一个问题当然是如何引发NullPointerException 。 要关注这个问题,我们可以简化如下代码片段:

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

下面是Effective Java 2nd Edition的第49条:引用基本types到装箱原语:

总而言之,只要有select,就优先使用原始图元(boxed primitive)。 原始types更简单,更快。 如果你必须使用盒装原语,小心! 自动装箱减less了使用装箱原语的冗长度,但不是危险。 当你的程序比较两个盒装原语与==运算符,它进行身份比较,这几乎肯定不是你想要的。 当你的程序进行混合types的计算时,涉及盒装和非盒装原语,它会取消装箱,当你的程序拆箱时,它会抛出NullPointerException 。 最后,当你的程序设置原始值时,可能会导致代价高昂的不必要的对象创build。

有些地方你别无select,只能使用盒装原语,例如generics,否则你应该认真考虑是否使用盒装原语的决定是合理的。

相关问题

  • Java和C#中的int和Integer有什么区别?
  • 为什么在Java中自动装箱允许我有一个布尔值3个可能的值?
  • 是否保证新的Integer(i)==我在Java? (是!!!)
  • 在Java中比较两个整数是否会发生自动拆箱? (没有!!!)
  • Java的noob:generics只有对象? (是的,很不幸的)

http://konigsberg.blogspot.com/2008/04/integergetinteger-are-you-kidding-me.html

getInteger'确定具有指定名称的系统属性的整数值。

你要这个:

 Integer.parseInt("123") 

请检查方法getInteger()的文档。 在此方法中, String参数是一个系统属性,用于确定具有指定名称的系统属性的整数值。 这里所讨论的“123”不是任何系统属性的名称。 如果你想把这个String转换为int ,那么使用方法int num = Integer.parseInt("123")