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

时间:2010-06-26 09:18:11

标签: java integer nullpointerexception api-design autoboxing

以下代码抛出NullPointerException

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

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

发生了什么事?

3 个答案:

答案 0 :(得分:202)

大图

这里有两个问题:

  • Integer getInteger(String)不符合您的想法
    • 在这种情况下返回null
  • Integerint的分配会导致自动取消装箱
    • 由于Integernull,因此会引发NullPointerException

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

参考

Integer API参考


Integer.getInteger

以下是文档对此方法的作用所说的内容:

  

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

换句话说,此方法与将String解析为int/Integer值无关,而是与System.getProperty方法有关。

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

同样地,Return of the Puzzlers: Schlock and Awe (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。最后,当您的程序框原始值时,它可能导致代价高昂且不必要的对象创建。

有些地方你别无选择,只能使用盒装基元,例如:泛型,但除此之外你应该认真考虑是否有合理使用盒装基元的决定。

相关问题

答案 1 :(得分:15)

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

  

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

你想要这个:

Integer.parseInt("123")

答案 2 :(得分:5)

请检查方法getInteger()的文档。 在此方法中,String参数是一个系统属性,用于确定具有指定名称的系统属性的整数值。 “123”不是任何系统属性的名称,如here所述。 如果要将此String转换为int,请将该方法用作 int num = Integer.parseInt("123")