疑惑
- 无意间看到一个三目运算,
(true ? 97 : 'a'),本以为运算结果是97,但是代码执行的实际结果是a;为什么(true ? 97 : 'a')会得到和(false ? 97 : 'a')一样的结果? - 将代码改为
(true ? 98 : 'a')再试,得到的结果是b,才发现原来是自动类型转换造成的原因; - 写了无数次看似简单的三目运算,其实并没有那么简单;
例子代码
- 例子1:
public static void main(String[] args) { System.out.println(true ? 97 : 'a');//输出结果是a System.out.println(true ? 98 : 'a');//输出结果是b System.out.println(true ? 65536 : 'a');//输出结果是65536 System.out.println(true ? 'a' : 65536);//输出结果是97 } - 例子2:
public static void main(String[] args) { int i = 97; System.out.println(true ? 97 : 'a');//输出结果是a System.out.println(true ? i : 'a');//输出结果是97 System.out.println(false ? i : 'a');//输出结果是97 }
官方对三目运算的解释
- 官方原文
- 三目运算中,如果第二和第三个值可以转换为数值类型,则会有以下几种情况:
- 1.操作数其中一个是 byte 或 Byte 类型,而另一个是 short 或 Short 类型,那么这个表达式就是 short 类型;
- 2.操作数中的一个是类型 T (T 可以是 byte、short 或者是 char 类型),而另一个是 int 类型的常数,其可以用 T 类型来表示时,那么这个表达式就是 T 类型;
- 3.操作数中的一个是 Byte 类型,而另一个是 int 类型的常数,其可以用 byte 类型来表示,那么这个表达式就是 byte 类型;
- 4.操作数中的一个是 Short 类型,而另一个是 int 类型的常数,其可以用 short 类型来表示,那么这个表达式就是 short 类型;
- 5.操作数中的一个是 Character 类型,而另一个是 int 类型的常数,其可以用 char 类型来表示,那么这个表达式就是 char 类型,否则,双目数值提升(binary numeric promotion)会被用于操作数的类型中,条件表达式的类型是第二个和第三个操作数提升后的类型。注意:双目数值提升时进行拆箱转换和值集转换(value set conversion)
例子详解
例子1详解
-
例子1
System.out.println(true ? 97 : 'a');//输出结果是a,其中97是int类型,'a'是char类型,并且97在char的范围之内,所以运算结果会自动转换为char,得到结果为a; -
例子1
System.out.println(true ? 65536 : 'a');//输出结果是65536,其中65536是int类型,'a'是char类型,,但是65536超出了char的范围,所以65536不会转换为char,得到结果为65536; -
同理,
System.out.println(true ? 'a' : 65536);//输出结果是97,因为65536超出了char的范围,所以运算结果为int类型,得到结果为97; -
以上情况,对应解释中的第三条;
例子2详解
-
注意第2、3、4、5条解释中的这句话“
另一个是 int 类型的常数”;
意思就是三目运算中,int的值为常量,才会出现int转换为byte、short或者是char的情况;
如果int的值为变量,运算的结果会转换为int类型; -
例子2
System.out.println(true ? 97 : 'a');中,97是常量,并且97能被char表示,所以97类型转换为char,得到结果为a; -
例子2
System.out.println(true ? i : 'a');中,i是变量,所以运算结果会转换为int类型,得到结果为97;