疑惑
- 无意间看到一个三目运算,
(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
;