Java 小谜题:为什么出现空指针异常? 介绍
我被这个问题耽误了几分钟。所以,它可能会帮助其他人,这是一个有趣的错误。但解决了第一个问题,我又想到了另一个问题Java 小谜题:为什么出现空指针异常? 介绍,java,nullpointerexception,puzzle,Java,Nullpointerexception,Puzzle,我被这个问题耽误了几分钟。所以,它可能会帮助其他人,这是一个有趣的错误。但解决了第一个问题,我又想到了另一个问题 第一个难题: 考虑以下代码: public void setValue(ValueWrapper valueWrapper) { if (anotherValueWrapper == null) { anotherValueWrapper = new AnotherValueWrapper(); } ano
第一个难题: 考虑以下代码:
public void setValue(ValueWrapper valueWrapper) {
if (anotherValueWrapper == null) {
anotherValueWrapper = new AnotherValueWrapper();
}
anotherValueWrapper.setValue(valueWrapper == null ? null : valueWrapper.getValue());
}
事实:
public void setValue(ValueWrapper valueWrapper) {
if (anotherValueWrapper == null) {
anotherValueWrapper = new AnotherValueWrapper();
}
anotherValueWrapper.setValue(valueWrapper == null ? null : valueWrapper.getValue());
}
- 这段代码编译
- getter和setter是标准(只返回字段或设置字段)
第二个问题 好的,您会发现(或者可能不会):问题是当另一个ValueWrapper像这样编写时:
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);
或
由于另一个ValueWrapper.setValue
采用原语(long)而非long
(对象),if无法编译
但该代码编译:
anotherValueWrapper.setValue(valueWrapper == null ? null : valueWrapper.getValue());
为什么?因为
Long
和String
是不可交换的,但是Long
和null
是可交换的
anotherValueWrapper.setValue(null);
无法编译,因为无法将基元设置为null。另一个ValueWrapper对“value”字段使用long(原语)
anotherValueWrapper.setValue(valueWrapper == null ? "test": valueWrapper.getValue());
不编译,因为“test”是一个字符串,因此无法分配给长变量。With
anotherValueWrapper.setValue(valueWrapper == null ? null : valueWrapper.getValue());
null
实际上属于Long
类型,它尝试自动装箱到Long
,因此在执行setValue(null)或setValue(“test”)时抛出空指针异常,它显式地传入一个对象和一个字符串类,而它们与基本类型Long不匹配
但是,传入对象类型Long是可以的,因为Java的自动装箱特性可以在原语类型和对象包装器之间自动转换。将Long对象传入另一个ValueWrapper的setValue()方法时,它会在引擎盖下执行Long的longValue()方法,如果Long对象为null,则会导致NullPointerException。事实上,另一个ValueWrapper.setValue使用Long(原语)而不是Long(对象)所以奇怪的是,当使用这种语法时,编译器无法检测到这样一个空值