为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

神不在的星期二 2019-11-14 10:41:22
以下代码抛出NullPointerException:int num = Integer.getInteger("123");getInteger因为它是静态的,所以我的编译器是否调用null?那没有任何意义!发生了什么?
查看完整描述

3 回答

?
红颜莎娜

TA贡献1842条经验 获得超12个赞

大图景

这里有两个问题在起作用:


Integer getInteger(String) 没有按照你的想法去做

null在这种情况下返回

从Integer到的分配int会导致自动取消装箱

由于Integeris null,NullPointerException被抛出

要解析(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返回该属性。


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


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


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


道德

奇怪而可怕的方法潜伏在图书馆

有些名字听起来无害

如果您的代码行为不当

确保调用正确的方法

阅读图书馆文件

对于API设计人员

不要违反最小惊讶原则

不要违反抽象层次结构

不要将相似的名称用于行为截然不同的行为

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


Boolean.getBoolean(String)

Long.getLong(String)

在自动拆箱中

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


Integer someInteger = null;

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

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


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


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


查看完整回答
反对 回复 2019-11-14
  • 3 回答
  • 0 关注
  • 898 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信