3.3 三元运算符
Java也支持三元运算。之所以称为三元运算,是因为此运算中有三个被操作数,其语法如下:
(<逻辑表达式>)?<结果表达式1>:<结果表达式2>
其运算规则是:首先计算逻辑表达式的值,若为真则返回“<结果表达式1>”的值,否则返回“<结果表达式2>”的值,如下所示。
1 //代码实现 2 public class Sample3_9 3 { 4 public static void main(String args[]) 5 { 6 int a=6; 7 int b=10; 8 int c=a>b?a:b;//挑出a与b中较大的一个 9 System.out.println("a="+a+", b="+b+", a与b中比较大的为:"+c+"。"); 10 } 11 }
编译运行后,其结果如图3-13所示。
图3-13 Sample3_9的编译运行结果
提示:三元运算可以用后面章节介绍的if-else语句代替,三元运算结构简洁紧凑,而if-else语句通俗易懂。不同的是,三元运算有返回值。在实际开发中,建议不要滥用三元运算,否则很容易产生可读性很差的代码。
三元运算符中的结果表达式1和2如果为基本类型,则要求其类型是兼容的。也就是说如果结果表达式1和2的运算结果类型不同,其值类型要可以相互转换;如果不能转换,则编译报错。例如,下面的表达式说明了这个问题。
(a>b)?true:12
· 此三元运算的第一个可能返回值是“true”,其是boolean型的。
· 第二个可能返回值是“12”,其是int型的。
· boolean型与int型是不可转换的,因此编译报错。
提示:如果表达式1、2 为引用类型,则永远都是对的,因为三元表达式的返回类型将设置为两个表达式类型的最小公共父类类型,而Java中的所有类都继承自java.lang.Object类。
对于三元运算符返回值类型与表达式1、2类型间的关系,有如下规则。
· 对于基本数据类型,如果两个表达式类型不同,则对int型以下(包括int)的字面常量将尽量进行窄化。如果不能进行窄化,最后返回级别高的类型。
· 窄化时要求字面常量的值在窄化后的类型范围内,如12能窄化为byte型,129则不行。
· 变量不能进行窄化,按级别高的类型返回。
· 对于引用类型,表达式的返回类型设置为两个表达式类型的最小公共父类类型。
例如,有下面的代码片段。
1 (a>b)?((byte)1234):123; 2 (a>b)?(12):123; 3 (a>b)?12:123L; 4 (a>b)?c:123; //c为int型变量
如上表达式计算后,结果类型将如下所示。
· 第1行返回值为byte型,因为“(byte)1234”为byte型,“123”字面常量在byte范围内,进行窄化。
· 第2行返回值为int型,两个字面常量都是int型的,不存在窄化问题。
· 第3行返回值为long型,“123L”是long型字面常量,不进行窄化,最后表达式返回long型。
· 第4行返回值为int型,c是变量,为int型,“123”也将被看作int型。
提示:上面这些规则都是为了使三元表达式能有唯一的返回值类型(一个表达式当然不能有多个返回值类型),且返回值类型尽量窄化。