【问题标题】:Strange Java behaviour. Ternary operator奇怪的 Java 行为。三元运算符
【发布时间】:2013-07-29 21:28:07
【问题描述】:

为什么这段代码有效?

Float testFloat = null;
Float f = true ? null : 0f;

为什么会抛出异常?

Float testFloat = null;
Float f = true ? testFloat : 0f;

但最奇怪的是,这段代码居然也运行成功,没有任何异常:

Float testFloat = null;
Float f = testFloat;

Java 的三元运算符似乎改变了这种行为。谁能解释一下这是为什么?

【问题讨论】:

  • 我用 JDK 7u25 运行它,它没有抛出任何异常。
  • 第三个代码不能抛出异常:你声明一个变量,将其设置为空,然后声明另一个变量并将其设置为第一个为空的值。不能抛出异常

标签: java operator-keyword ternary


【解决方案1】:

行为在JLS - Conditional Operator中指定:

如果第二个和第三个操作数之一是原始类型 T,而另一个的类型是对 T 应用装箱转换(第 5.1.7 节)的结果,则 条件表达式的类型是T

强调我的。所以,在第 2nd 案例中:

Float f = true ? testFloat : 0f;

由于第三个操作数是原始类型(T),因此表达式的类型将是浮点类型 - T。因此,unboxing testFloat(当前是 null 引用)对 float 的引用将导致 NPE


至于第一个st案例,相关部分是最后一个:

否则,第二个和第三个操作数分别是 S1 和 S2 类型。令 T1 为对 S1 应用装箱转换产生的类型,令 T2 为对 S2 应用装箱转换产生的类型。条件表达式的类型是将捕获转换(第 5.1.10 节)应用到 lub(T1, T2)(第 15.12.2.7 节)的结果。

所以,根据这个:

null type - S1
float     - S2

null type - T1 (boxing null type gives null type)
Float     - T2 (float boxed to Float)

然后条件表达式的类型变为-Float。不需要拆箱null,因此不需要NPE

【讨论】:

  • 哦...我现在明白了!非常感谢您的回答!
  • 我找不到为什么true ? null : 0f 可以的确切规则。你能确定 JLS 中的那个部分吗?或者这只是“如果第二个和第三个操作数具有相同的类型(可能是空类型),那么这就是条件表达式的类型。”,其中0f 被装箱为Float?跨度>
  • @Heuster。让我看看。
  • 这个解释很好
  • @BrianAgnew。谢谢:)
猜你喜欢
  • 2016-07-14
  • 2013-10-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-10-20
  • 1970-01-01
相关资源
最近更新 更多