我最近在一些代码中工作,并且当被同事审查时,被告知我通过删除双值的手动装箱而犯了一个错误。我没有想过这个,但我之所以这样做,是因为IntelliJ建议我改变它,所以我做了。
我被这位同事指向了Effective Java(第2版)的第221页,其中讨论了Boxed原语如何为null,并且依赖于自动装箱可以导致潜在的空指针异常(除其他外)......但是在这种情况下,我正在删除手动装箱并让编译器处理它。
但为什么这很重要?如果我的方法需要Double
作为参数,并且先前已经传入new Double(5.0)
,而是将其更改为5
,那么潜在的影响是什么?
答案 0 :(得分:5)
如果我有一个方法需要Double,作为参数,并且之前传递了新的Double(5.0),但是将其更改为5,那么潜在的含义是什么?
没有不良影响,因为这是拳击,而不是取消装箱。因此,您不会在这里获得NPE,如果您在传递值的方法中将其取消装箱,也不会获得NPE。
事实上,将5
作为Double
参数传递与传递new Double(5.0)
并不完全相同 - 它实际上是Double.valueOf(5.0)
。其优点在于Javadoc:
返回表示指定double值的Double实例。如果不需要新的Double实例,通常应优先使用此方法,而不是构造函数Double(double),因为此方法可能通过缓存频繁请求的值来显着提高空间和时间性能。
因此,通过传递Double.valueOf(5.0)
,您可以获得更好的性能,因为缓存;但你可以使用远不那么冗长的5
代替。
但是,如果你有重载,你必须要小心:这些方法中的某些方法可能比采用Double
的方法具有更具体的方法签名,因此会优先调用。
答案 1 :(得分:4)
你给的拳击例子完全没问题。 问题是拆箱。如果你试图从null对象包装器获取原始数据,你将拥有NPE:
Double d = null;
double d1 = d; // here you will get NPE