Java JLS 是否指定提升原始包装器类型?

Does the Java JLS specify promotion of primitive wrapper types?

我对这个程序的输出有点迷惑:

public class xx {
    public static void main(String[] args) throws Exception {
        Number x = false ? new Long(123) : new Integer(456);
        System.out.println(x + " isa " + x.getClass().getName());
    }
}

这是它的输出:

456 isa java.lang.Long

编译器似乎是 "promoting" 类型为 IntegerLong 的对象,就像它通常会提升原始值一样。我从未听说过 object promotion,这种行为似乎非常令人惊讶。

我的问题:根据 JLS,这真的是正确的行为吗?如果是的话,我想尽可能地看到一个参考。

或者这是某种自动装箱疯狂的编译器错误?

我正在使用:

java version "1.8.0_60"
Java(TM) SE Runtime Environment (build 1.8.0_60-b27)
Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode)

如果bc分别是Long和Integer,在this table中,JLS定义表达式a ? b : c的类型。

表达式的类型确实是Long,确实存在Integer to Long的二进制数值提升(bnp)

规则更详细here:

The type of a numeric conditional expression is determined as follows:

[...]

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.

这实际上是二进制数值提升(JLS, Section 5.6.2).

When an operator applies binary numeric promotion to a pair of operands, each of which must denote a value that is convertible to a numeric type, the following rules apply, in order:

  1. If any operand is of a reference type, it is subjected to unboxing conversion (§5.1.8).

  2. Widening primitive conversion (§5.1.2) is applied to convert either or both operands as specified by the following rules:

    • If either operand is of type double, the other is converted to double.

    • Otherwise, if either operand is of type float, the other is converted to float.

    • Otherwise, if either operand is of type long, the other is converted to long.

    • Otherwise, both operands are converted to type int.

Binary numeric promotion is performed on the operands of certain operators:

...

  • In certain cases, the conditional operator ? : (§15.25)

因此,操作数被取消装箱并且 456 被扩大到 456L

此外,LongInteger 的具体情况在条件运算符 JLS Section 15.25, Table 15.25-C.

的 JLS 部分中明确涵盖

bnp(Long,Integer)

其中 "bnp" 表示二进制数字提升。因此,条件运算符表达式的类型为 long,它被装箱到 Long 以分配给 Number.