探讨一个关于三元运算的诡异问题
代码如下
Java code
public class Test{
public static void main(String args[ ]){
char ch = 'E';
int x = 3;
Object obj = false ? x : ch;
System.out.println(obj.getClass().getSimpleName());
System.out.println(false ? x : ch);
System.out.println(false ? 3 : 'E');
}
}
其执行结果为:
Integer
69
E
以前我一直以为是三元运算符前后类型不一样的时候 如果能互转 那么低位的会转成高位的
但是在这里出现了这个问题:三元运算符的前后直接用值和用相同值的变量 其结果不一样
有朋友对这个有清晰的理解没 分享一下...
------解决方案--------------------
双目数值类型提升
学名叫:binary numberic promotion
不要在条件运算的操作数中使用不同的数据类型,并且条件运算符与 if...else 结构性质并不是完全相同的。
下面是 Java Language Specification 上关于条件表达式的说明
● 如果第二和第三个操作数在可以转换为数值类型时,会有以下几种情况:
◆ 操作数其中一个是 byte 或 Byte 类型,而另一个是 short 或 Shoft 类型,那么这个表达式就是 shoft 类型
◆ 操作数中的一个是类型 T (T 可以是 byte、short 或者是 char 类型),而另一个是 int 类型的常数,其可以用 T 类型来表示时,那么这个表达式就是 T 类型
◆ 操作数中的一个是 Byte 类型,而另一个是 int 类型的常数,其可以用 byte 类型来表示,那么这个表达式就是 byte 类型
◆ 操作数中的一个是 Short 类型,而另一个是 int 类型的常数,其可以用 short 类型来表示,那么这个表达式就是 short 类型
◆ 操作数中的一个是 Character 类型,而另一个是 int 类型的常数,其可以用 char 类型来表示,那么这个表达式就是 char 类型
◆ 否则,双目数值提升(binary numeric promotion)会被用于操作数的类型中,条件表达式的类型是第二个和第三个操作数提升后的类型。注意:双目数值提升时进行拆箱转换和值集转换(value set conversion)
PS:这里只是部分的,更多的看 http://java.sun.com/docs/books/jls/third_edition/html/expressions.html#341287
在这里会用到最后一点,即进行双目数值提升,所谓的双目数值提升通俗点的描述是:两个数根据一定的规则把其中一个的类型转为另一个类型。
根据 Java Language Specification 中关于双目数值提升的描述
http://java.sun.com/docs/books/jls/third_edition/html/conversions.html#170983
● 如果任意一个操作数是引用类型,则会进行自动拆箱转换(unboxing conversion),然后:
● 如果任意一个操作数是 double 类型,那另外一个会被转换成为 double 类型
● 否则,如果任意一个操作数是 float 类型,那另外一个会被转换成为 float 类型
● 否则,如果任意一个操作数是 long 类型,那另外一个会被转换成为 long 类型
● 否则两个操作数都会被转换为 int 类型