出自java puzzle
public void phymes(){
Random rnd = new Random();
StringBuffer word = null;
switch(rnd.nextInt(2)){
case 1: word = new StringBuffer('P');
case 2: word = new StringBuffer('G');
default: word = new StringBuffer('M');
}
word.append('a');
word.append('i');
word.append('n');
System.out.println(word);
}
乍一看,这个程序可能会在一次又一次的运行中,以相等的概率打印出Pain,Gain或 Main。看起来该程序会根据随机数生成器所选取的值来选择单词的第一个字母:0选M,1选P,2选G。谜题的题目也许已经给你提供了线索,它实际上既不会打印Pain,也不会打印Gain。也许更令人吃惊的是,它也不会打印Main,并且它的行为不会在一次又一次的运行中发生变化,它总是在打印ain。
有三个bug凑到一起引发了这种行为。你完全没有发现它们吗?第一个bug是所选取的随机数使得switch语句只能到达其三种情况中的两种。
Random.nextInt(int)的规范描述道:“返回一个伪随机的、均等地分布在从0(包括)到指定的数值(不包括)之间的一个int数值”[Java-API]。这意味着表达式rnd.nextInt(2)可能的取值只有0和1,Switch语句将永远也到不了case 2分支,这表示程序将永远不会打印Gain。nextInt的参数应该是3而不是2。
这是一个相当常见的问题源,被熟知为“栅栏柱错误(fencepost error)”。这个名字来源于对下面这个问题最常见的但却是错误的答案,如果你要建造一个100英尺长的栅栏,其栅栏柱间隔为10英尺,那么你需要多少根栅栏柱呢?11根或9根都是正确答案,这取决于是否要在栅栏的两端树立栅栏柱,但是10根却是错误的。要当心栅栏柱错误,每当你在处理长度、范围或模数的时候,都要仔细确定其端点是否应该被包括在内,并且要确保你的代码的行为要与其相对应。
第二个bug是在不同的情况(case)中没有任何break语句。不论switch表达式为何值,该程序都将执行其相对应的case以及所有后续的case[JLS 14.11]。因此,尽管每一个case都对变量word赋了一个值,但是总是最后一个赋值胜出,覆盖了前面的赋值。最后一个赋值将总是最后一种情况(default),即new StringBuffer{'M'}。这表明该程序将总是打印Main,而从来不打印Pain或Gain。
在switch的各种情况中缺少break语句是非常常见的错误。从5.0版本起,javac提供了-Xlint:fallthrough标志,当你忘记在一个case与下一个case之间添加break语句是,它可以生成警告信息。不要从一个非空的case向下进入了另一个case。这是一种拙劣的风格,因为它并不常用,因此会误导读者。十次中有九次它都会包含错误。如果Java不是模仿C建模的,那么它倒是有可能不需要break。对语言设计者的教训是:应该考虑提供一个结构化的switch语句。
最后一个,也是最微妙的一个bug是表达式new StringBuffer('M')可能没有做哪些你希望它做的事情。你可能对StringBuffer(char)构造器并不熟悉,这很容易解释:它压根就不存在。StringBuffer有一个无参数的构造器,一个接受一个String作为字符串缓冲区初始内容的构造器,以及一个接受一个int作为缓冲区初始容量的构造器。在本例中,编译器会选择接受int的构造器,通过拓宽原始类型转换把字符数值'M'转换为一个int数值77[JLS 5.1.2]。换句话说,new StringBuffer('M')返回的是一个具有初始容量77的空的字符串缓冲区。该程序余下的部分将字符a、i和n添加到了这个空字符串缓冲区中,并打印出该字符串缓冲区那总是ain的内容。
分享到:
相关推荐
谜题23:不劳无获 第4章 循环之谜 谜题24:尽情享受每一个字节 谜题25:无情的增量操作 谜题26:在循环中 谜题27:变幻莫测的i值 谜题28:循环者 谜题29:循环者的新娘 谜题30:循环者的爱子 谜题3l:循环者的鬼魂 ...
谜题23:不劳无获 49 第4 章循环之谜 53 谜题24:尽情享受每一个字节 53 谜题25:无情的增量操作 55 谜题26:在循环中 57 谜题27:变幻莫测的i值 59 谜题28:循环者 61 谜题29:循环者的新娘 63 谜题30:...
II 30 谜题22:URL的愚弄 32 谜题23:不劳无获 32 Java谜题3——循环谜题 35 谜题24:尽情享受每一个字节 35 谜题25:无情的增量操作 37 谜题26:在循环中 38 谜题27:变幻莫测的i值 39 ...
谜题23:不劳无获 Java谜题3——循环谜题 谜题24:尽情享受每一个字节 谜题25:无情的增量操作 谜题26:在循环中 谜题27:变幻莫测的i值 谜题28:循环者 谜题29:循环者的新娘 谜题30:循环者的爱子 谜题31...
大学生个人总结文体劳方面个人.docx
《无废话XML》——劳虎 经典书籍电子版,内含各章节examples,是学习XML的绝佳资料.
劳办发(1997)116号[参考].pdf
句容市初中英语联合集备学案No pains ,no gains.不劳无获 九年级上册Unit 5 Grammar 主备: 后白中学丁孝宏审核: 天王中学庄成欢 【课前导学】 1. 预习P70-71后,
这不是原创设计,是国外设计师设计的一款很有创意的双层纸结构,分享给大家
斯特里劳气质调查表.doc
学习xml技术必备的书籍----胭脂虎、劳虎
XXXX年征管查考试题解析(货劳税部分).docx
德智体美劳自我鉴定范文.doc
餐饮业_团餐_人均劳效.xls
ERP与商务智能(BI)- 池邦劳, 蓬天公司 企业信息化与资源管理系统——解读ERP ERP管理思想 ERP由美国加特纳公司在90年代初期首先提出,当时的解释是根据计算机技术的发展和供需链管理,推论各类制造业在信息时代...
最新电子书,案例丰富。 E-commerce. Business. Technology. Society. 11Eprovides you with an in-depth introduction to the field of e-commerce....take advantage of the evolving world of opportunity offered ...
为全面贯彻党的教育方针,落实立德树人根本任务,培养德智体美劳全面发展的社会主义建设者和接班人。我校《小学劳动教育课程开发实践研究》课题组开展一系列的劳动实践活动。我校把劳动教育融入到学生的校园生活、...
促进学生德智体美劳全面发展工作措施.pdf
大学生德智体美劳自我评价100字.docx
德体智美劳全面发展议论文作文范例10篇.pdf