我对这个程序的输出感到有些神秘:
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());
}
}
Run Code Online (Sandbox Code Playgroud)
这是它输出的内容:
456 isa java.lang.Long
Run Code Online (Sandbox Code Playgroud)
它出现在编译器"促进"类型的对象Integer来Long,就像它通常会促进原始值.我从来没有听说过对象推广,这种行为似乎非常令人惊讶.
我的问题:根据JLS,这是非常正确的行为吗?如果是这样,我希望尽可能看到参考.
或者这是一种autoboxing-gone-wild编译器错误?
我正在使用:
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)
Run Code Online (Sandbox Code Playgroud)
这实际上是二进制数字提升(JLS,第 5.6.2 节)。
\n\n\n\n\n当运算符将二进制数字提升应用于一对操作数时(每个操作数必须表示可转换为数字类型的值),将按顺序应用以下规则:
\n\n\n
\n\n- \n
如果任何操作数是引用类型,则对其进行拆箱转换(\xc2\xa75.1.8)。
- \n
加宽基元转换 (\xc2\xa75.1.2) 用于按照以下规则指定转换一个或两个操作数:
\n\n\n
- \n
如果其中一个操作数的类型为 double,则另一个操作数将转换为 double。
- \n
否则,如果任一操作数的类型为 float,则另一个将转换为 float。
- \n
否则,如果任一操作数的类型为 long,则另一个将转换为 long。
- \n
否则,两个操作数都转换为 int 类型。
对某些运算符的操作数执行二进制数字提升:
\n\n...
\n\n\n
\n- 在某些情况下,条件运算符 ? :(\xc2\xa715.25)
\n
因此,操作数被拆箱并且456被扩展为456L。
此外,条件运算符的 JLS 部分(JLS 第 15.25 节,表 15.25-C)Long明确涵盖了和的具体情况。Integer
\n\n\nbnp(长整型)
\n
其中“bnp”表示二进制数字提升。因此,条件运算符表达式的类型为long,它被装箱到 aLong以分配给 a Number。
| 归档时间: |
|
| 查看次数: |
99 次 |
| 最近记录: |