Java条件运算符?:结果类型 [英] Java conditional operator ?: result type

查看:151
本文介绍了Java条件运算符?:结果类型的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我对条件运算符有点疑惑。请考虑以下两行:

I'm a bit puzzled about the conditional operator. Consider the following two lines:

Float f1 = false? 1.0f: null;
Float f2 = false? 1.0f: false? 1.0f: null;

为什么f1变为空,第二个语句抛出NullPointerException?

Why does f1 become null and the second statement throws a NullPointerException?

Langspec-3.0 para 15.25 sais:

Langspec-3.0 para 15.25 sais:


否则,第二和第三个操作数分别为S1和S2类型。
设T1是将拳击转换应用到S1所产生的类型,而让
T2是将拳击转换应用到S2所产生的类型。条件表达式的
类型是将捕获转换
(§5.1.10)应用于lub(T1,T2)(§15.12.2.7)的结果。

Otherwise, the second and third operands are of types S1 and S2 respectively. Let T1 be the type that results from applying boxing conversion to S1, and let T2 be the type that results from applying boxing conversion to S2. The type of the conditional expression is the result of applying capture conversion (§5.1.10) to lub(T1, T2) (§15.12.2.7).

因此对于 false?1.0f:null T1是Float,T2是null类型。但 lub(T1,T2)的结果是什么?这段15.12.2.7有点太多了......

So for false?1.0f:null T1 is Float and T2 is the null type. But what is the result of lub(T1,T2)? This para 15.12.2.7 is just a bit too much ...

BTW,我在Windows上使用1.6.0_18。

BTW, I'm using 1.6.0_18 on Windows.

PS:我知道浮动f2 =假? (浮动)1.0f:假? (Float)1.0f:null; 不会抛出NPE。

PS: I know that Float f2 = false? (Float) 1.0f: false? (Float) 1.0f: null; doesn't throw NPE.

推荐答案

区别在于编译时表达式的静态类型:

E1: `(false ? 1.0f : null)`
    - arg 2 '1.0f'           : type float,
    - arg 3 'null'           : type null 
    - therefore operator ?:  : type Float (see explanation below)
    - therefore autobox arg2
    - therefore autobox arg3

E2: `(false ? 1.0f : (false ? 1.0f : null))`
    - arg 2 '1.0f'                    : type float
    - arg 3 '(false ? 1.0f : null)'   : type Float (this expr is same as E1)
    - therefore, outer operator ?:    : type float (see explanation below)
    - therefore un-autobox arg3



详细说明:



通过阅读规范并从你得到的结果向后工作。归结为f2 内部条件的第三个操作数的类型是null类型,而f2 外部条件的第三个操作数的类型被认为是Float。

Detailed Explanation:

Here's my understand from reading through the spec and working backwards from the result you got. It comes down to the type of the third operand of the f2 inner conditional is null type while the type of the third operand of the f2 outer conditional is deemed to be Float.

注意:重要的是要记住,类型的确定和装箱/拆箱代码的插入是在编译时完成的。装箱/拆箱代码的实际执行是在运行时完成的。

Note: Its important to remember that the determination of type and the insertion of boxing/unboxing code is done at compile-time. Actual execution of boxing/unboxing code is done at run-time.

Float f1 = (false ? 1.0f : null);
Float f2 = (false ? 1.0f : (false ? 1.0f : null));

f1条件和f2内部条件:(false?1.0f: null)

The f1 conditional and the f2 inner conditional: (false ? 1.0f : null)

f1条件和f2内部条件相同:(false?1.0f:null)。 f1条件和f2内部条件中的操作数类型是:

The f1 conditional and the f2 inner conditional are identical: (false ? 1.0f : null). The operand types in the f1 conditional and the f2 inner conditional are:

type of second operand = float
type of third operand = null type (§4.1)

§15.25被传递出来,确实应用了这个最终评估:

Most of the rules in §15.25 are passed up and this final evaluation is indeed applied:


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

Otherwise, the second and third operands are of types S1 and S2 respectively. Let T1 be the type that results from applying boxing conversion to S1, and let T2 be the type that results from applying boxing conversion to S2. The type of the conditional expression is the result of applying capture conversion (§5.1.10) to lub(T1, T2) (§15.12.2.7).



S1 = float
S2 = null type
T1 = Float
T2 = null type
type of the f1 and f2 inner conditional expressions = Float

因为对于f1,赋值是Float引用变量,表达式(null)的结果被成功分配。

Since for f1, the assignment is to a Float reference variable, the result of the expression (null) is successfully assigned.

对于f2外部条件:(假?1.0f:[f2内部条件])

For f2 outer conditional: (false ? 1.0f : [f2 inner conditional])

对于f2外部条件,类型为:

For the f2 outer conditional, the types are:

type of second operand = float
type of third operand = Float

注意操作数类型与直接引用 null 文字的f1 / f2内部条件相比的差异(§4.1)。由于具有2个数字可转换类型的这种差异,此规则来自§15.12.2.7适用:

Note the difference in operand types compared to the f1/f2 inner conditionals that reference the null literal directly (§4.1). Because of this difference of having 2 numeric-convertible types, this rule from §15.12.2.7 applies:



  • 否则,如果第二个和第三个操作数具有可转换的类型(§5.1.8)数字类型,然后有几种情况:...

  • Otherwise, if the second and third operands have types that are convertible (§5.1.8) to numeric types, then there are several cases: ...


  • 否则,二进制数字促销(§5.6.2)应用于操作数类型,条件表达式的类型是第二个和第三个操作数的提升类型。请注意,二进制数字促销会执行取消装箱转换§5.1.8)和值集转换(§5.1.13

  • Otherwise, binary numeric promotion (§5.6.2) is applied to the operand types, and the type of the conditional expression is the promoted type of the second and third operands. Note that binary numeric promotion performs unboxing conversion (§5.1.8) and value set conversion (§5.1.13).

由于对f2内部条件(null)的结果执行了拆箱转换,因此会引发NullPointerException。

Because of the unboxing conversion performed on the result of the f2 inner conditional (null), a NullPointerException is raised.

这篇关于Java条件运算符?:结果类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆