3

介绍

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


第一个谜题:

考虑以下代码:

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; }
}

和价值包装器:

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());

if 由于anotherValueWrapper.setValue需要原始(长)而不是Long(对象)而无法编译。

但是这段代码编译:

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

为什么 ?

4

4 回答 4

2

当您执行 setValue(null) 或 setValue("test") 时,它会显式传入一个 Object 和一个 String 类,并且它们与原始类型 long 不匹配。

但是,传入对象类型 Long 是可以的,因为 Java 的自动装箱功能会自动在原始类型及其对象包装器之间进行转换。当您将 Long 对象传递给 anotherValueWrapper 的 setValue() 方法时,它会在底层执行 Long 的 longValue() 方法,如果 Long 对象为 null,它将导致 NullPointerException。

于 2013-02-21T16:03:38.107 回答
2

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

null确实是Long尝试自动装箱long并因此引发空指针异常的类型

于 2013-02-21T15:57:40.010 回答
0

因为LongString不能互换,但是Longnull是..

于 2013-02-21T15:55:54.750 回答
0
anotherValueWrapper.setValue(null);

无法编译,因为您无法将原语设置为 null。AnotherValueWrapper 使用 long - 一种原语 - 用于“值”字段。

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

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

于 2013-02-21T15:56:19.043 回答