为啥 int num = Integer.getInteger("123") 会抛出 NullPointerException?

Posted

技术标签:

【中文标题】为啥 int num = Integer.getInteger("123") 会抛出 NullPointerException?【英文标题】:Why does int num = Integer.getInteger("123") throw NullPointerException?为什么 int num = Integer.getInteger("123") 会抛出 NullPointerException? 【发布时间】:2011-03-08 14:11:28 【问题描述】:

以下代码抛出NullPointerException

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

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

发生了什么事?

【问题讨论】:

使用 Integer.getValue() 代替。这篇博文很好地解释了原因:konigsberg.blogspot.in/2008/04/… 【参考方案1】:

大局

这里有两个问题:

Integer getInteger(String) 没有做你认为的事情 在这种情况下返回nullIntegerint 的分配导致自动拆箱 由于IntegernullNullPointerException 被抛出

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

参考文献

Java Language Guide/Autoboxing

Integer API 参考

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

开启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的这些方法:

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

相关问题

Most Astonishing Violation of the Principle of Least Astonishment Most awkward/misleading method in Java Base API ?

关于自动拆箱

当然,另一个问题是NullPointerException 是如何被抛出的。为了关注这个问题,我们可以将sn-p简化如下:

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

这里引用 Effective Java 2nd Edition,Item 49:Prefer primitive types to boxed primitives:

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

有些地方你别无选择,只能使用盒装图元,例如泛型,否则您应该认真考虑使用盒装原语的决定是否合理。

相关问题

What is the difference between an int and an Integer in Java/C#? Why does autoboxing in Java allow me to have 3 possible values for a boolean? Is it guaranteed that new Integer(i) == i in Java?(是的!!!) When comparing two Integers in Java does auto-unboxing occur? (不!!!) Java noob: generics over objects only?(是的,很遗憾)

【讨论】:

所以Integer.getInteger(s) 大致相当于Integer.parseInt(System.getProperty(s))?我想我更喜欢第二个,尽管它更冗长,因为它突出了您从系统属性中提取信息的事实。 我一发表评论,就意识到我可以看看 Integer 类的实际来源!我在正确的轨道上,除了它使用Integer.decode 而不是Integer.parseInt,它寻找前导0x0 将数字分别解析为十六进制或八进制。 对于那些问为什么NullPointerException的人:programmers.stackexchange.com/questions/158908/… @Oracle 你能弃用 java.lang.Integer.getInteger(String) 吗?【参考方案2】:

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

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

你想要这个:

Integer.parseInt("123")

【讨论】:

【参考方案3】:

请查看方法getInteger() 的文档。 在此方法中,String 参数是一个系统属性,它确定具有指定名称的系统属性的整数值。正如here 所讨论的,“123”不是任何系统属性的名称。 如果您想将此字符串转换为int,则使用该方法作为 int num = Integer.parseInt("123").

【讨论】:

以上是关于为啥 int num = Integer.getInteger("123") 会抛出 NullPointerException?的主要内容,如果未能解决你的问题,请参考以下文章

为啥 int num = Integer.getInteger("123") 会抛出 NullPointerException?

为啥我在 Python 中没有得到 333

关于C语言宏定义,这样为啥不行

为啥 InnoDB 表大小比预期大得多?

为啥这个字符串排列代码超过了递归限制?

为啥变量赋值中的空格会在 Bash 中出错? [复制]