参见英文答案 >
Java conditional operator ?: result type5个
> Why does the ternary operator unexpectedly cast integers?2
请考虑下列代码:
> Why does the ternary operator unexpectedly cast integers?2
请考虑下列代码:
Object obj = true ? new Integer(0) : new Long(1); System.out.println(obj.getClass() + "\nvalue = " + obj);
其结果是:
class java.lang.Long value = 0
代替:
class java.lang.Integer value = 0
有人可以澄清为什么我们在Java中有这样的功能?对我来说很奇怪
你有什么例子可以用吗?
更新:
这是一个字节码,我们可以看到,那里有什么
NEW java/lang/Integer DUP LDC "0" INVOKESPECIAL java/lang/Integer.<init> (Ljava/lang/String;)V INVOKEVIRTUAL java/lang/Integer.intValue ()I I2L INVOKESTATIC java/lang/Long.valueOf (J)Ljava/lang/Long; ASTORE 1
解决方法
这里发生的是结果
>二进制数字升级使您的整型和长类型长期用作应用于条件运算符表达式的常用类型
>取消装箱这些包装对象
>然后对条件表达式的结果值进行装箱
条件运算符的第二和第三操作数必须最终具有相同的类型,这是表达式的结果类型.整数和长度当然不是同一类型.
但是,如JLS§15.25中所述,编译器将在确定应用于表达式的可能常用类型时应用binary numeric promotion.该部分有方便的表15.25-D,告诉我们,当第二个操作数的类型为整数,第三个操作数的类型为Long时,编译器将对Integer Long执行二进制数字升级.整数的二进制数字推广,长产量长.因此,条件运算符表达式的结果很长.
由于表达式的结果类型很长,所以Integer或Long将不得不被取消装箱(然后在Integer的情况下投射).
最后,你将它分配给一个对象,它强制拳击,并在Long中包裹长.因此,您最终得到一个Long,其中包含与输出匹配的值0.
因此,如果我们忽略了这样一个事实:编译器会优化下面的一半,因为它处理一个常量表达式,由于代码中的真实(我已经使用了下面的标志),那个代码最终就是这样的:
Object obj = Long.valueOf(flag ? (long)(new Integer(0)).intValue() : (new Long(1)).longValue()); System.out.println(obj.getClass() + "\nvalue = " + obj);
>(long)(new Integer(0)).intValue()表示取消打包整数,并将其转换为long,因此它与表达式结果类型相匹配.>(New Long(1)).longValue()表示拆分Long,因此它与表达式结果类型匹配.>而Long.valueOf代表最后的拳击.