为什么int num = Integer.getInteger(“123”)抛出NullPointerException?
以下代码引发NullPointerException
:
int num = Integer.getInteger("123");
我的编译器调用getInteger
为null,因为它是静态的吗? 这没有任何意义!
发生了什么?
大的图片
这里有两个问题:
-
Integer getInteger(String)
不会做你认为它- 在这种情况下它返回
null
- 在这种情况下它返回
- 从
Integer
到int
的赋值会导致自动拆箱- 由于
Integer
为null
,所以抛出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
。
换句话说,这个方法与将一个String
parsing为一个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")
。