在三目运算符java开发的环境下可以简单的理解为双目运算符的类型转换问题(便于理解)。其具体规则总结如下:
1)如果定义了数据类型的变量与未定义变量的数值共同参与三元运算符的后双目运算,,那么返回的结果就是范围大 (精度高)类型
2)如果两个定义了数据类型的变量共同参与三元运算符的后双目运算,那么返回的结果就是范围大(精度高)类型
3)如果直接进行数值的比较,会自动转型成为范围大(精度高)的数据类型
而jvm在给数值分配数据类型的时候会选取刚好能装下该数据大小精度的数据类型进行分配(99.0为float,99为byte/short),在java中常见数据类型其范围从小到大(精度由高到低):byte<short<char<int<float<double(注意: 此处不再是隐式转换)。 当类型相同时,表达式返回该类型
char a='a';
int i=96;
//规则1,定义了数据类型的变量与未定义变量的数值,结果自动转换为精度高的
System.out.println(2==2?i:9.0); //输出 96.0
//jvm给数值分配的数据类型,98并不是int类型的,而是byte/short(反编译字节码文件可看出),故结果会变为ASCII码98对应的字符
//java规范中提到 若两个操作数中有一个是常量数字S,另外一个是表达式,且其类型为T,那么,若数字S在T的范围内,則转换为T类型;若S超出了T类型的范围,则T转换为S类 因为10是常量,可以被char表示,输出的结果是char型的,所以是x。
System.out.println(2==2?98:a); //输出 b
System.out.println(false ? 2147483647L : a);//此时输出的是long类型 输出 97
//规则2,两个已经定义数据类型的变量,结果自动转换为精度高的
System.out.println(2==2?a:i); //输出 97
//规则3,两个常量,结果自动转换为精度高的
System.out.println(2==2?99:9.0); //输出 99.0
System.out.println(2==2?99:'b'); //byte char比较 输出 c
三元操作符必须要返回一个数据。而且类型要确定,不可能条件为真时返回int类型,条件为假时返回float类型,编译器是不允许如此的,所以它就会进行类型转换了. 会根据运算符的精确度类型进行自动类型转换,System.out.println(2==2?99:9.0) 由于后面有一个9.0,所以后面的99会被转换成99.0,所以输出的是99.0.
@Test
public void intInteger() {
boolean switchLog = true;
Integer oneExpre = null
Integer result = switchLog ? oneExpre : 0;
System.out.println(result);//报空指针异常
}
@Test
public void intInteger() {
boolean switchLog = true;
Integer oneExpre = null;
Integer result = switchLog ? oneExpre : new Integer(0);
System.out.println(result);//输出null
}
报错的情况:
这种情况下,“表达式1” 结果是 null,而“ 表达式2 ” 是基本类型。大胆猜想一下,当执行时,先执行 “表达式1” 的得到返回结果 null ,此时 null 是一个特殊的值,并不知道其“具体的类型”,然后尝试着和 “表达式2” 进行统一类型,发现 “表达式2” 是 int 类型,并进行强转或者封装类型转基本类型,报NPE。
未报错的情况:
和报错情况不同的是,“表达式2”本身就是 Integer 类型,封装类型本身支持 null 类型赋值,便省去了类型强转的步骤,则不报错。