Java中三目运算符的语法:表达式1?表达式2:表达式3;
先看下面两个代码段:
int i=1;
System.out.println("i="+((i<1)?1.0:2));
char a='a';
int j=1;
System.out.println(false?j:a);
System.out.println(false?1:a);
System.out.println(true?1:a);
结果是多少?
i=2.0
97
a
(1对应的char值)
为什么会是这样呢?
简单解释一下:(具体参照这里)
第一个代码中,表达式1i<1是false,结果应该是表达式3的值2,但因为三目运算符中表达式2的值为1.0,根据Java语言的定义,表达式的运算结果类型会根据运算的精度类型进行自动类型转换,1.0比2的精度高,所以结果是2.0。
第二个代码中,
System.out.println(false?j:a);
结果应该是表达式3 a 的值,但因为a的类型是char,表达式2的结果类型是int,所以最后结果类型自动转换为int类型,是a的ASCII码值:97。
对于:
System.out.println(false?1:a);
结果应该是表达式3 a 的值,但因为a的类型是char,表达式2的结果类型是常量,根据Java三目运算符的定义:若三目运算符中的两个表达式有一个是常量表达式,另一个是类型T的表达式,且常量表达式可以被T表示,则输出结果是T类型。因为1可以被char表示,所以最后结果类型为char类型,是a的值:a。
对于:
System.out.println(true?1:a);
和上面的一样,结果应是char类型,是1的对于的char值(一个笑脸符号)。
一般情况下if-else可以和三目表达式替换使用,但有如下区别:
Object o1 = true ? new Integer(1) : new Double(2.0);
Object o2;
if (true)
o2 = new Integer(1);
else
o2 = new Double(2.0);
System.out.println(o1);
System.out.println(o2);
结果:1.0
1
三目运算符是有一定的语言规范的。在运用不恰当的时候会导致意想不到的问题。常见的使用三目运算符导致的问题,就是三目运算符和基本数据类型及其对应包装类自动拆箱自动装箱过程产生的,参考这里。
再看2个也是有关三目运算符和自动装箱自动拆箱相关的莫名其妙的空指针异常:
Map<String,Boolean> map = new HashMap<String, Boolean>();
Boolean bb = (map!=null ? map.get("b") : false);//java.lang.NullPointerException
Integer i =1;
if (i==1){
i = null;
}
Double d =2.0;
Object obj = true ? i : d; // java.lang.NullPointerException
System.out.println(obj);
把代码反编译后:
Map map = new HashMap();
Boolean bb = Boolean.valueOf(map != null ? ((Boolean)map.get("b")).booleanValue() : false);
Integer i = Integer.valueOf(1);
if (i.intValue() == 1) {
i = null;
}
Double d = Double.valueOf(2.0D);
Object obj = Double.valueOf(i.intValue());
System.out.println(obj);
红色标注就是空指针的原因,所以使用基本数据类型及其对应的包装类时,需特别注意。