小谜题:为什么空指针异常?

时间:2013-02-21 15:51:11

标签: java nullpointerexception puzzle

简介

我几分钟就被困在这个问题上了。所以,它可能会帮助别人,这是一个有趣的错误。但解决第一个问题却让我想到了另一个问题。


第一个难题:

请考虑以下代码:

public void setValue(ValueWrapper valueWrapper) {

        if (anotherValueWrapper == null) {
            anotherValueWrapper = new AnotherValueWrapper();
        }

        anotherValueWrapper.setValue(valueWrapper == null ? null : valueWrapper.getValue());
    }

事实:

  • 此代码编译
  • getter和setter是标准(没有更多的代码而不是返回字段或设置它)

问题

在执行期间,有一种情况是代码失败并返回空指针异常。

第一个难题是:此代码何时会导致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());

为什么?

4 个答案:

答案 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)

由于LongString不可互换,但Longnull是..

答案 3 :(得分:0)

anotherValueWrapper.setValue(null);

无法编译,因为您无法将基元设置为null。 AnotherValueWrapper使用long - 一个原语 - 用于'value'字段。

anotherValueWrapper.setValue(valueWrapper == null ? "test": valueWrapper.getValue());

不编译,因为“test”是一个字符串,因此无法分配给长变量。