【问题标题】:java ternary conditions strange null pointer exception [duplicate]java三元条件奇怪的空指针异常[重复]
【发布时间】:2016-10-31 22:14:04
【问题描述】:

谁能解释一下为什么在第一种情况下检测到空指针,但在其他情况下没有?

也许他总是看第一种,但为什么他只在条件为假的情况下才这样做..

@Test
public void test1() {
    final Integer a = null;

    final Integer b = false ? 0 : a;

    //===> NULL POINTER EXCEPTION
}

@Test
public void test2() {
    final Integer b = false ? 0 : null;

    //===>NOT NULL POINTER EXCEPTION
}

@Test
public void test3() {
    final Integer a = null;

    final Integer b = true ? 0 : a;

    //===>NOT NULL POINTER EXCEPTION
}

@Test
public void test4() {
    final Integer a = null;

    final Integer b = false ? new Integer(0) : a;

    //===> NOT NULL POINTER EXCEPTION
}

@Test
public void test5() {
    final Integer a = null;

    final Integer b = false ? a : 0;

    //===>NOT NULL POINTER EXCEPTION
}

【问题讨论】:

  • 可能的欺骗:stackoverflow.com/questions/12763983/…(我不投票不关闭问题)
  • "如果第二个和第三个操作数之一是原始类型 T,而另一个的类型是对 T 应用装箱转换(第 5.1.7 节)的结果,则条件表达式是 T。”那么为什么 test3 和 test5 没有抛出 NPE 呢?抱歉我没听懂

标签: java nullpointerexception ternary-operator


【解决方案1】:

当你使用三元运算符时,

 flag  ? type1 : type2

在转换时,Type1 和 type2 必须是相同的类型。首先它实现了type1,然后实现了type2。

现在看看你的案例

 final Integer b = false ? 0 : a;

因为type10 并且它作为一个原语,并且因为a 试图将它转换为primitive。因此是空指针。

与同样棘手的测试5

 final Integer b = false ? a : 0;

由于 a 的类型为 Integer 0,因此被装箱为包装整数并分配给 LHS。

【讨论】:

  • 这个答案在不同的层次上解释了上一个答案在说什么。 (null.intValue() 被调用的原因。很好的答案 ;-)
  • 感谢您的回答,您能解释一下为什么 test3 没有抛出 NPE 吗?为什么转换没有应用于“type1”,所以将 a 转换为原语?
  • final Integer b = true ? 0 : a; 因为标志为真,所以它选择了 0。并且装箱发生在 new Integer(0) 上。零是一个有效的整数,对吧?
  • 转换发生在真正的元素上,而不是第一个。我懂了 !谢谢
【解决方案2】:

我认为在这种情况下 a 将拆箱为 int,因为 0 是 int 。这意味着调用 null.intValue() 并获得 NPE

@Test
public void test1() {
    final Integer a = null;

    final Integer b = false ? 0 : a;

【讨论】:

  • 好吧,我不确定这就是原因。那 test4 怎么不抛出 NPE 呢?
  • 问题在于 java 将 a 解释为 int 因为“?”
  • 它实际上会被un装箱到int。但我想知道为什么 test2 似乎将其装箱,而 test1 似乎将其拆箱......但@DylanMeeus,那是因为在测试 4 中没有对 null 调用任何内容,因为那里没有进行(取消)装箱。
  • 在 test4 中,a 是整数,所以 b 也会被解释为整数。
  • If one of the second and third operands is of primitive type T, and the type of the other is the result of applying boxing conversion (§5.1.7) to T, then the type of the conditional expression is T. - 这就是测试 2 有效而测试 1 失败的原因。测试 2 中的 null 没有拆箱,因为它不符合引用的标准(取自 JLS)。
猜你喜欢
  • 2011-12-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-04-28
  • 1970-01-01
  • 1970-01-01
  • 2018-02-14
相关资源
最近更新 更多