日期:2014-05-20  浏览次数:20635 次

探讨一个关于三元运算的诡异问题
代码如下

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 类型