我几分钟就被困在这个问题上了。所以,它可能会帮助别人,这是一个有趣的错误。但解决第一个问题却让我想到了另一个问题。
请考虑以下代码:
public void setValue(ValueWrapper valueWrapper) {
if (anotherValueWrapper == null) {
anotherValueWrapper = new AnotherValueWrapper();
}
anotherValueWrapper.setValue(valueWrapper == null ? null : valueWrapper.getValue());
}
事实:
问题
在执行期间,有一种情况是代码失败并返回空指针异常。
第一个难题是:此代码何时会导致NullPointerException?
不要看第二个问题,因为如果你没有找到第一个问题,这是一个扰流板。
好的,你找到它(或者不是):问题是当AnotherValueWrapper写成这样的时候:
public class AnotherValueWrapper {
private long value;
public long getValue() { return value; }
public void setValue(long value) { this.value = value; }
}
和ValueWrapper:
public class ValueWrapper {
private Long value;
public Long getValue() { return value; }
public void setValue(Long value) { this.value = value; }
}
这是第二个问题:
如果我写:
anotherValueWrapper.setValue(null);
或
anotherValueWrapper.setValue(valueWrapper == null ? "test": valueWrapper.getValue());
如果由于anotherValueWrapper.setValue
采用原始(长)而不是Long
(对象)这一事实而无法编译。
但是这段代码编译:
anotherValueWrapper.setValue(valueWrapper == null ? null : valueWrapper.getValue());
为什么?
答案 0 :(得分:2)
使用
anotherValueWrapper.setValue(valueWrapper == null ? null : valueWrapper.getValue());
null
实际上属于Long
类型,它会尝试自动装箱到long
,因此会抛出空指针异常
答案 1 :(得分:2)
当你执行setValue(null)或setValue(“test”)时,它显式传入一个Object和一个String类,并且它们与long类型不匹配。
但是,传入对象类型Long是可以的,因为Java的自动装箱功能可以自动在基本类型和对象包装器之间进行转换。当你将Long对象传递给anotherValueWrapper的setValue()方法时,它会在引擎盖下执行Long的longValue()方法,如果Long对象为null,则会导致NullPointerException。
答案 2 :(得分:0)
由于Long
和String
不可互换,但Long
和null
是..
答案 3 :(得分:0)
anotherValueWrapper.setValue(null);
无法编译,因为您无法将基元设置为null。 AnotherValueWrapper使用long - 一个原语 - 用于'value'字段。
anotherValueWrapper.setValue(valueWrapper == null ? "test": valueWrapper.getValue());
不编译,因为“test”是一个字符串,因此无法分配给长变量。