Java条件运算符?:结果类型

Wan*_*ick 36 java type-conversion nullpointerexception conditional-operator

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

Float f1 = false? 1.0f: null;
Float f2 = false? 1.0f: false? 1.0f: null;
Run Code Online (Sandbox Code Playgroud)

为什么f1变为null而第二个语句抛出NullPointerException?

Langspec-3.0 para 15.25 sais:

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

所以对于false?1.0f:nullT1是Float而T2是null类型.但结果是lub(T1,T2)什么?第15.12.2.7段只是有点太多了......

顺便说一句,我在Windows上使用1.6.0_18.

PS:我知道Float f2 = false? (Float) 1.0f: false? (Float) 1.0f: null;不会抛出NPE.

Ber*_*t F 26

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

摘要

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
Run Code Online (Sandbox Code Playgroud)

详细说明:

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

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

Float f1 = (false ? 1.0f : null);
Float f2 = (false ? 1.0f : (false ? 1.0f : null));
Run Code Online (Sandbox Code Playgroud)

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

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

type of second operand = float
type of third operand = null type (§4.1)
Run Code Online (Sandbox Code Playgroud)

§15.25中的大多数规则都已通过,最终的评估确实适用:

否则,第二和第三操作数分别是S1和S2类型.设T1是将拳击转换应用于S1所产生的类型,让T2为应用到S2的装箱转换所产生的类型.条件表达式的类型是将捕获转换(第5.1.10节)应用于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
Run Code Online (Sandbox Code Playgroud)

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

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

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

type of second operand = float
type of third operand = Float
Run Code Online (Sandbox Code Playgroud)

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

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

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

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