这个谜题将测试你对条件操作符的掌握程度,这个操作符有一个更广为人知的名字:问号冒号操作符。下面的程序将会打印出什么呢?


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); } }

这个程序由两个变量声明和两个print语句构成。第一个print语句计算条件表达式(true ? x : 0)并打印出结果,这个结果是char类型变量x的值’X’。而第二个print语句计算表达式(false ? i : x)并打印出结果,这个结果还是依旧是’X’的x,因此这个程序应该打印XX。然而,如果你运行该程序,你就会发现它打印出来的是X88。这种行为看起来挺怪的。第一个print语句打印的是X,而第二个打印的却是88。它们的不同行为说明了什么呢?

答案就在规范有关条件表达式部分的一个阴暗的角落里。请注意在这两个表达式中,每一个表达式的第二个和第三个操作数的类型都不相同:x是char类型的,而0和i都是int类型的。就像在谜题5的解答中提到的,混合类型的计算会引起混乱,而这一点比在条件表达式中比在其它任何地方都表现得更明显。你可能考虑过,这个程序中两个条件表达式的结果类型是相同的,就像它们的操作数类型是相同的一样,尽管操作数的顺序颠倒了一下,但是实际情况并非如此。

确定条件表达式结果类型的规则过于冗长和复杂,很难完全记住它们,但是其核心就是以下三点:

1,如果第二个和第三个操作数具有相同的类型,那么它就是条件表达式的类型。换句话说,你可以通过绕过混合类型的计算来避免大麻烦。

2,如果一个操作数的类型是T,T表示byte、short或char,而另一个操作数是一个int类型的常量表达式,它的值是可以用类型T表示的,那么条件表达式的类型就是T。

3,否则,将对操作数类型运用二进制数字提升,而条件表达式的类型就是第二个和第三个操作数被提升之后的类型。

2、3两点对本谜题是关键。在程序的两个条件表达式中,一个操作数的类型是char,另一个的类型是int。在两个表达式中,int操作数都是0,它可以被表示成一个char。然而,只有第一个表达式中的int操作数是常量(0),而第二个表达式中的int操作数是变量(i)。因此,第2点被应用到了第一个表达式上,它返回的类型是char,而第3点被应用到了第二个表达式上,其返回的类型是对int和char运用了二进制数字提升之后的类型,即int。

条件表达式的类型将确定哪一个重载的print方法将被调用。对第一个表达式来说,PrintStream.print(char)将被调用,而对第二个表达式来说,PrintStream.print(int)将被调用。前一个重载方法将变量x的值作为Unicode字符(X)来打印,而后一个重载方法将其作为一个十进制整数(88)来打印。至此,谜题被解开了。

总之,通常最好是在条件表达式中使用类型相同的第二和第三操作数。否则,你和你的程序的读者必须要彻底理解这些表达式行为的复杂规范。

对语言设计者来说,也许可以设计一个牺牲掉了部分灵活性,但是增加了简洁性的条件操作符。例如,要求第二和第三操作数必须就有相同的类型,这看起来就很合理。或者,条件操作符可以被定义为对常量没有任何特殊处理。为了让这些选择对程序员来说更加容易接受,可以提供用来表示所有原始类型字面常量的语法。这也许确实是一个好注意,因为它增加了语言的一致性和完备性,同时又减少了对转型的需求。

谜题8:Dos Equis的更多相关文章

  1. [变]C#谜题(1-10)表达式篇

    [变]C#谜题(1-10)表达式篇 最近偶然发现了<Java谜题>,很有意思,于是转到C#上研究一下. 本篇是关于表达式的一些内容. 谜题1:奇数性(负数的取模运算) 下面的方法意图确定它 ...

  2. 高点击率的Banner设计14招

    英文原文:14 design tips for more clickable banner ads 译文:http://www.uisdc.com/banner-click-rate 虽然互联网发展迅 ...

  3. 程序员需要经纪人吗?10x 最好的程序员其生产力相当于同行的 10 倍~

    原文地址 10x 起源于技术界一个流行的说法,即最好的程序员是超级明星,其生产力相当于同行的 10 倍: Google 园区以好玩的设施闻名:小憩舱.球坑.按摩.干洗.随便吃到饱的自助餐.(为了拍人才 ...

  4. DOS批处理高级教程

    转载-->http://blog.csdn.net/lanbing510/article/details/7461073 前言 本教程主要引用伤脑筋版主的系列文章,同时参考引用[英雄]教程等其他 ...

  5. 如何使用dos命令打开当前用户、当前日期、当前时间以及当前用户加当前时间?

    1.dos命令安装mysqld --stall.启动net start mysql.进入MySQL数据库mysql -uroot -p后,输入select user();当前用户 select cur ...

  6. 如何使用dos命令查看MySQL当前使用的数据库?

    1.dos命令安装mysqld --stall.启动net start mysql.进入MySQL数据库mysql -uroot -p后,输入select database(); 如图:

  7. 怎样在Dos里切换盘符

    一:在Dos里切换盘符 a:在电脑左下角右击显示图片;(我用的是win10系统,其他系统类似) b:点击运行,输入cmd; c:点击确定: d:输入盘符:(如f:) 或F: 只写字母,不写分号是不行的 ...

  8. Java在DOS命令下的运行及其API文档制作过程

    该文档主要描述java程序在DOS命令下的运行,以及一些常用的命令 常用DOS命令: d: 回车 盘符切换 dir(directory):列出当前目录下的文件以及文件夹 md (make direct ...

  9. 如何dos中查看当前MySQL版本信息?

    dos中MySQL安装服务成功--启动服务成功--登录MySQL成功后输入:select version();  如图:

随机推荐

  1. BZOJ4550 小奇的博弈 【Nimk游戏 + dp + 组合数】

    题目 这个游戏是在一个1*n的棋盘上进行的,棋盘上有k个棋子,一半是黑色,一半是白色.最左边是白色棋子,最右边 是黑色棋子,相邻的棋子颜色不同. 小奇可以移动白色棋子,提比可以移动黑色的棋子,它们每次 ...

  2. [hdu 2102]bfs+注意INF

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2102 感觉这个题非常水,结果一直WA,最后发现居然是0x3f3f3f3f不够大导致的……把INF改成I ...

  3. org.apache.hadoop.hdfs.server.datanode.DataNode: Exception in receiveBlock for block

    Hbase依赖的datanode日志中如果出现如下报错信息:DataXceiverjava.io.EOFException: INFO org.apache.hadoop.hdfs.server.da ...

  4. linux 学习好资源

    Linux-Wiki.cn http://linux-wiki.cn/wiki/zh-hans/Linux%E7%9B%AE%E5%BD%95%E7%BB%93%E6%9E%84    Linux目录 ...

  5. vue入门知识

    vue的特点在于:响应的数据绑定.组合的视图组件. vue的文件,分成三个部分<template>html模板</template>  <script>js< ...

  6. CSS3学习笔记之立体线框球形动画

    效果截图: HTML代码: <div class="ball-box"> <div class="ball"> <div clas ...

  7. 我们用CloudStack做什么

    原文地址:http://www.sdfengxi.com/?p=376 我想很多同学会有类似的疑问,就是我配置好了CloudStack或者OpenStack之类的环境之后能够提供什么服务或者应用呢?下 ...

  8. java简单发送邮件

    需要的jar 据说是: <dependency> <groupId>javax.mail</groupId> <artifactId>mail</ ...

  9. Javadoc注释的用法

    Javadoc注释的用法   相关阅读:http://blog.163.com/hui_san/blog/static/5710286720104191100389/ Java 文档// 注释一行/* ...

  10. 【bzoj1010-toy】斜率优化入门模板

    dsy1010: [HNOI2008]玩具装箱 [题目描述] 有n个数,分成连续的若干段,每段(假设从第j个到第i个组成一段)的分数为 (X-L)^2,X为j-i+Sigma(Ck) i<=k& ...