java解惑之表达式之谜(谜题8)

谜题8: Dos Equis
这个谜题将测试你对条件操作符(冒号问号操作符)的掌握程序,看下面的程序会打印出什么结果?
public class DosEquis{
 public static void main(String[] args){   
  char x = 'X';
  int i = 0;
  System.out.println(true ? x : 0);
  System.out.println(false ? i : x);
 }
}
       只要对条件操作符了解的都知道第一条打印语句应该打印的是字符X,第二条打印语句也应该打印出字符X,即打印结果应当是XX。而运行后,实际打印出来的却是X88,那这是什么原因导致的呢?
之前在谜题5中,我们讨论过混合类型的计算会引起混乱,而看上面程序的两个条件表达式中,每个条件表达式的第二和第三个操作数都分别是char类型和int类型以及int类型和char类型,是不同的类型,所以我们可以看出,混合类型计算引起的混乱,在条件表达式中表现的比其他任何地方都更明显。但你可能会说,既然两个表达式的第二第三个操作数都是char类型和int类型(仅仅是颠倒了顺序而已),并且两个表达式的结果类型也是相同的,那为什么第一条打印语句打印出来的结果是正确的呢?其实不然,尽管操作数的顺序颠倒了,但是实际情况并非我们想象中的那么简单。我们先来看下确定条件表达式结果类型的三点核心规则:
       1.如果第二个和第三个操作数具有相同的类型,那么它就是条件表达式的类型。换句话说,可以通过绕过混合类型的计算来避免大麻烦;
       2.如果一个操作数的类型是T,T表示byte、short或char,而另外一个操作数是一个int类型的常量表达式,它的值可以用类型T表示,那么条件表达式的类型就是T;
       3.否则,将对操作数类型进行二进制数字提升,而条件表达式的类型就是第二个和第三个操作数被提升之后的类型。
       对于本谜题而言,第二条和第三条规则是关键。很清楚的能看出,第一条打印语句中的第三个操作数是一个int类型的常量表达式,并且能用char类型表示,符合第二条规则,所以打印出来的条件表达式的类型为char,即打印出字符X。而第二条打印语句中的第二个操作数i是int类型的变量,那么就会执行第三条规则,打印出来的条件表达式的类型是对int和char进行二进制数字提升之后的类型,即int类型数值88。条件表达式的类型将确定调用哪一个重载的print方法。对第一个表达式来说,将调用PrintStream.print(char),而对第二个表达式来说,将调用PrintStream.print(int)。前一个重载方法将变量x的值作为Unicode字符(X)打印,而后一个重载方法将其作为一个十进制整数(88)打印。那么,我们应该怎样才能使程序打印出我们想要的结果呢?我们只需要将final修饰符用于i的声明,可以把i转变为一个常量表达式,从而让程序打印出XX,但是这仍旧会引起混乱。为了消灭这种混乱,最好的方法就是将i的类型从int更改为char。
       总之,通常最好是在条件表达式中使用类型相同的第二和第三操作数。否则,你和你程序的阅读者必须彻底理解这些表达式行为的复杂规范。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值