Java If 语句的简写形式在返回的对象之一为 null 时返回 NullPointerException



为什么这段代码返回错误:java.lang.NullPointerException

Object obj = null;
Long lNull = null;
Long res = obj == null ? lNull : 10L;

但是以下方法没有任何错误:

Object obj = null;
Long res = obj == null ? null : 10L;

在第二种情况下,编译器可以推断null必须是Long类型。在第一种情况下,它不会 - 并假设表达式返回long 。您可以看到这种情况(即修复它(如下,

Long res = obj == null ? lNull : (Long) 10L;

这不会产生 NullPointerException。

发生此错误是因为在您的情况下,标准要求取消装箱类型的值:

如果第二个和第三个操作数中的一个是基元类型 T,而另一个操作数的类型是将装箱转换 (§5.1.7( 应用于T的结果,则条件表达式的类型为 T 个。

在你的情况下,Tlong的,因为10Llong的,lNullLong的,即将装箱转换应用于long的结果。

该标准进一步指出,

如有必要,将对结果执行拆箱转换。

这就是导致异常的原因。请注意,如果反转条件,将不再引发异常:

Long res = obj != null ? lNull : 10L;

您可以通过显式请求Long而不是使用 long 来解决问题,即

Long res = obj == null ? lNull : Long.valueOf(10L);

JLS 第 15.25 节讨论了第二和第三操作数类型的各种组合的条件运算符表达式的类型。 有许多表将所有相关组合中的两种类型映射到结果类型。

3rd → long
2nd ↓  
...
Long  long
...
null  lub(null,Long)

你的第一个示例有一个Long和一个long,这会产生long 。 这需要lNull拆箱,这解释了NullPointerException

您的第二个示例有一个null文字(不是null变量(和一个long。 这会导致"lub(null,Long("或Long,并且不执行拆箱,因此未观察到NPE。

你可以通过使用你的第一个示例或通过将10L转换为Long来避免 NPE,因为nullLong产生一个Long

3rd → Long
2nd ↓  
...
Long  Long

相关内容

  • 没有找到相关文章

最新更新