logo资料库

"java解惑" PDF版本.pdf

第1页 / 共165页
第2页 / 共165页
第3页 / 共165页
第4页 / 共165页
第5页 / 共165页
第6页 / 共165页
第7页 / 共165页
第8页 / 共165页
资料共165页,剩余部分请下载后查看
目录
Java谜题1——表达式谜题
谜题1:奇数性
谜题2:找零时刻
谜题3:长整除
谜题4:初级问题
谜题5:十六进制的趣事
谜题6:多重转型
谜题7:互换内容
谜题8:Dos Equis
谜题9:半斤
谜题10:八两
Java谜题2——字符谜题
谜题11:最后的笑声
谜题12:ABC
谜题13:畜牧场
谜题14:转义字符的溃败
谜题15:令人晕头转向的Hello
谜题16:行打印程序
谜题17:嗯?
谜题18:字符串奶酪
谜题19:漂亮的火花
谜题20:我的类是什么?
谜题21:我的类是什么?II
谜题22:URL的愚弄
谜题23:不劳无获
Java谜题3——循环谜题
谜题24:尽情享受每一个字节
谜题25:无情的增量操作
谜题26:在循环中
谜题27:变幻莫测的i值
谜题28:循环者
谜题29:循环者的新娘
谜题30:循环者的爱子
谜题31:循环者的鬼魂
谜题32:循环者的诅咒
谜题33:循环者遇到了狼人
谜题34:被计数击倒了
谜题35:一分钟又一分钟
Java谜题4——异常谜题
谜题36:优柔寡断
谜题37:极端不可思议
谜题38:不受欢迎的宾客
谜题39:您好,再见!
谜题40:不情愿的构造器
谜题41:域和流
谜题42:异常为循环而抛
谜题43:异常地危险
谜题44:切掉类
谜题45:令人疲惫不堪的测验
Java谜题5——类谜题
谜题46:令人混淆的构造器案例
谜题47:啊呀!我的猫变成狗了
谜题48:我所得到的都是静态的
谜题49:比生命更大
谜题50:不是你的类型
谜题51:那个点是什么?
谜题52:合计数的玩笑
谜题53:按你的意愿行事
谜题54:Null与Void
谜题55:特创论
Java谜题6——库谜题
谜题56:大问题
谜题57:名字里有什么?
谜题58:产生它的散列码
谜题59:什么是差?
谜题60:一行的方法
谜题61:日期游戏
谜题62:名字游戏
谜题63:更多同样的问题
谜题64:按余数编组
谜题65:一种疑似排序的惊人传奇
Java谜题7——更多的类谜题
谜题66:一件私事
谜题67:对字符串上瘾
谜题68:灰色的阴影
谜题69:黑色的渐隐
谜题70:一揽子交易
谜题71:进口税
谜题72:终极危难
谜题73:你的隐私正在公开
谜题74:同一性的危机
谜题75:头还是尾?
名字重用的术语表
覆写(override)
隐藏(hide)
重载(overload)
遮蔽(shadow)
遮掩(obscure)
Java谜题8——更多的库谜题
谜题76:乒乓
谜题77:搞乱锁的妖怪
谜题78:反射的污染
谜题79:这是狗的生活
谜题80:更深层的反射
谜题81:烧焦到无法识别
谜题82:啤酒爆炸
谜题83:诵读困难者的一神论
谜题84:被粗暴地中断
谜题85:惰性初始化
Java谜题9——高级谜题
谜题86:有毒的括号垃圾
谜题87:紧张的关系
谜题88:原生类型的处理
谜题89:泛型迷药
谜题90:荒谬痛苦的超类
谜题91:序列杀手
谜题92:双绞线
谜题93:类的战争
谜题94:迷失在混乱中
谜题95:只是些甜点
Java™ Puzzlers: Traps, Pitfalls, and Corner Cases (Java 解惑) Joshua Bloch/ Neal Gafter June 24, 2005 1
本书特写了 95 个有关 Java 或其类库的陷阱和缺陷的谜题,其中大多数谜题都采用了短程序的 方式,这些程序的行为与其看似的大相径庭。在每个谜题之后都给出了详细的解惑方案,这些 解惑方案超越了对程序行为的简单解释,向读者展示了如何一劳永逸地避免底层的陷阱与缺 陷。 本书趣味十足、寓教于乐,适合于具备 Java 知识的学习者和有编程经验的 Java 程序员。 · 本书评语: “每一种编程语言都有其怪癖的行为,这本生动的书通过趣味十足和发人深省的编程谜题揭示了 Java 编程语言的奇异之处”。 ——Guy Steele,SunJ 院士,《Java 语言规范》的合著者 “我笑了,我叫起来了,我钦佩地举起了双手。” ——Tim Peierls,Prior Artisans 公司总裁,JSR 166 专家组成员 2
目 录 Java谜题 1——表达式谜题 ......................................................................1 谜题 1:奇数性........................................................................................................................1 谜题 2:找零时刻....................................................................................................................2 谜题 3:长整除........................................................................................................................3 谜题 4:初级问题....................................................................................................................5 谜题 5:十六进制的趣事........................................................................................................6 谜题 6:多重转型....................................................................................................................7 谜题 7:互换内容....................................................................................................................9 谜题 8:Dos Equis .................................................................................................................10 谜题 9:半斤..........................................................................................................................11 谜题 10:八两........................................................................................................................13 Java谜题 2——字符谜题 ........................................................................14 谜题 11:最后的笑声............................................................................................................14 谜题 12:ABC .......................................................................................................................15 谜题 13:畜牧场....................................................................................................................17 谜题 14:转义字符的溃败....................................................................................................18 谜题 15:令人晕头转向的Hello...........................................................................................20 谜题 16:行打印程序............................................................................................................21 谜题 17:嗯?........................................................................................................................22 谜题 18:字符串奶酪............................................................................................................23 谜题 19:漂亮的火花............................................................................................................25 谜题 20:我的类是什么?....................................................................................................26 谜题 21:我的类是什么?II .................................................................................................28 谜题 22:URL的愚弄............................................................................................................29 谜题 23:不劳无获................................................................................................................30 Java谜题 3——循环谜题 ........................................................................33 谜题 24:尽情享受每一个字节............................................................................................33 谜题 25:无情的增量操作....................................................................................................34 谜题 26:在循环中................................................................................................................35 谜题 27:变幻莫测的i值.......................................................................................................37 谜题 28:循环者....................................................................................................................38 谜题 29:循环者的新娘........................................................................................................39 谜题 30:循环者的爱子........................................................................................................40 谜题 31:循环者的鬼魂........................................................................................................41 谜题 32:循环者的诅咒........................................................................................................42 3
谜题 33:循环者遇到了狼人................................................................................................44 谜题 34:被计数击倒了........................................................................................................45 谜题 35:一分钟又一分钟....................................................................................................47 Java谜题 4——异常谜题 ........................................................................48 谜题 36:优柔寡断................................................................................................................48 谜题 37:极端不可思议........................................................................................................49 谜题 38:不受欢迎的宾客....................................................................................................51 谜题 39:您好,再见!........................................................................................................53 谜题 40:不情愿的构造器....................................................................................................54 谜题 41:域和流....................................................................................................................56 谜题 42:异常为循环而抛....................................................................................................57 谜题 43:异常地危险............................................................................................................60 谜题 44:切掉类....................................................................................................................62 谜题 45:令人疲惫不堪的测验............................................................................................65 Java谜题 5——类谜题 ............................................................................66 谜题 46:令人混淆的构造器案例........................................................................................66 谜题 47:啊呀!我的猫变成狗了........................................................................................68 谜题 48:我所得到的都是静态的........................................................................................70 谜题 49:比生命更大............................................................................................................71 谜题 50:不是你的类型........................................................................................................73 谜题 51:那个点是什么?....................................................................................................74 谜题 52:合计数的玩笑........................................................................................................78 谜题 53:按你的意愿行事....................................................................................................80 谜题 54:Null与Void .............................................................................................................81 谜题 55:特创论....................................................................................................................82 Java谜题 6——库谜题 ............................................................................85 谜题 56:大问题....................................................................................................................85 谜题 57:名字里有什么?....................................................................................................86 谜题 58:产生它的散列码....................................................................................................88 谜题 59:什么是差?............................................................................................................90 谜题 60:一行的方法............................................................................................................91 谜题 61:日期游戏................................................................................................................93 谜题 62:名字游戏................................................................................................................95 谜题 63:更多同样的问题....................................................................................................96 谜题 64:按余数编组............................................................................................................97 谜题 65:一种疑似排序的惊人传奇....................................................................................99 Java谜题 7——更多的类谜题 ..............................................................102 谜题 66:一件私事..............................................................................................................102 谜题 67:对字符串上瘾......................................................................................................104 谜题 68:灰色的阴影..........................................................................................................106 4
谜题 69:黑色的渐隐..........................................................................................................108 谜题 70:一揽子交易..........................................................................................................109 谜题 71:进口税..................................................................................................................110 谜题 72:终极危难..............................................................................................................112 谜题 73:你的隐私正在公开..............................................................................................113 谜题 74:同一性的危机......................................................................................................115 谜题 75:头还是尾?..........................................................................................................116 名字重用的术语表.......................................................................................................118 Java谜题 8——更多的库谜题 ..............................................................120 谜题 76:乒乓......................................................................................................................120 谜题 77:搞乱锁的妖怪......................................................................................................122 谜题 78:反射的污染..........................................................................................................125 谜题 79:这是狗的生活......................................................................................................127 谜题 80:更深层的反射......................................................................................................130 谜题 81:烧焦到无法识别..................................................................................................131 谜题 82:啤酒爆炸..............................................................................................................133 谜题 83:诵读困难者的一神论..........................................................................................135 谜题 84:被粗暴地中断......................................................................................................136 谜题 85:惰性初始化..........................................................................................................137 Java谜题 9——高级谜题 ......................................................................140 谜题 86:有毒的括号垃圾..................................................................................................140 谜题 87:紧张的关系..........................................................................................................140 谜题 88:原生类型的处理..................................................................................................142 谜题 89:泛型迷药..............................................................................................................145 谜题 90:荒谬痛苦的超类..................................................................................................148 谜题 91:序列杀手..............................................................................................................150 谜题 92:双绞线..................................................................................................................153 谜题 93:类的战争..............................................................................................................154 谜题 94:迷失在混乱中......................................................................................................156 谜题 95:只是些甜点..........................................................................................................159 5
Java 谜题 1——表达式谜题 谜题 1:奇数性 return i % 2 == 1; 下面的方法意图确定它那唯一的参数是否是一个奇数。这个方法能够正确运转 吗? public static boolean isOdd(int i){ } 奇数可以被定义为被 2 整除余数为 1 的整数。表达式 i % 2 计算的是 i 整除 2 时所产生的余数,因此看起来这个程序应该能够正确运转。遗憾的是,它不能; 它在四分之一的时间里返回的都是错误的答案。 为什么是四分之一?因为在所有的 int 数值中,有一半都是负数,而 isOdd 方 法对于对所有负奇数的判断都会失败。在任何负整数上调用该方法都回返回 false ,不管该整数是偶数还是奇数。 这是 Java 对取余操作符(%)的定义所产生的后果。该操作符被定义为对于所 有的 int 数值 a 和所有的非零 int 数值 b,都满足下面的恒等式: (a / b) * b + (a % b) == a 换句话说,如果你用 b 整除 a,将商乘以 b,然后加上余数,那么你就得到了最 初的值 a 。该恒等式具有正确的含义,但是当与 Java 的截尾整数整除操作符 相结合时,它就意味着:当取余操作返回一个非零的结果时,它与左操作数具有 相同的正负符号。 当 i 是一个负奇数时,i % 2 等于-1 而不是 1, 因此 isOdd 方法将错误地返 回 false。为了防止这种意外,请测试你的方法在为每一个数值型参数传递负数、 零和正数数值时,其行为是否正确。 这个问题很容易订正。只需将 i % 2 与 0 而不是与 1 比较,并且反转比较的含 义即可: return i % 2 != 0; public static boolean isOdd(int i){ } 如果你正在在一个性能临界(performance-critical)环境中使用 isOdd 方法, 那么用位操作符 AND(&)来替代取余操作符会显得更好: public static boolean isOdd(int i){ return (i & 1) != 0; 1
} 总之,无论你何时使用到了取余操作符,都要考虑到操作数和结果的符号。该操 作符的行为在其操作数非负时是一目了然的,但是当一个或两个操作数都是负数 时,它的行为就不那么显而易见了。 谜题 2:找零时刻 请考虑下面这段话所描述的问题: Tom 在一家汽车配件商店购买了一个价值$1.10 的火花塞,但是他钱包中都是两 美元一张的钞票。如果他用一张两美元的钞票支付这个火花塞,那么应该找给他 多少零钱呢? 下面是一个试图解决上述问题的程序,它会打印出什么呢? public static void main(String args[]){ System.out.println(2.00 - 1.10); } public class Change{ } 你可能会很天真地期望该程序能够打印出 0.90,但是它如何才能知道你想要打 印小数点后两位小数呢? 如果你对在 Double.toString 文档中所设定的将 double 类型的值转换为字符串 的规则有所了解,你就会知道该程序打印出来的小数,是足以将 double 类型的 值与最靠近它的临近值区分出来的最短的小数,它在小数点之前和之后都至少有 一位。因此,看起来,该程序应该打印 0.9 是合理的。 这么分析可能显得很合理,但是并不正确。如果你运行该程序,你就会发现它打 印的是 0.8999999999999999。 问题在于 1.1 这个数字不能被精确表示成为一个 double,因此它被表示成为最 接近它的 double 值。该程序从 2 中减去的就是这个值。遗憾的是,这个计算的 结果并不是最接近 0.9 的 double 值。表示结果的 double 值的最短表示就是你所 看到的打印出来的那个可恶的数字。 更一般地说,问题在于并不是所有的小数都可以用二进制浮点数来精确表示的。 如果你正在用的是 JDK 5.0 或更新的版本,那么你可能会受其诱惑,通过使用 printf 工具来设置输出精度的方订正该程序: //拙劣的解决方案——仍旧是使用二进制浮点数 System.out.printf("%.2f%n",2.00 - 1.10); 2
这条语句打印的是正确的结果,但是这并不表示它就是对底层问题的通用解决方 案:它使用的仍旧是二进制浮点数的 double 运算。浮点运算在一个范围很广的 值域上提供了很好的近似,但是它通常不能产生精确的结果。二进制浮点对于货 币计算是非常不适合的,因为它不可能将 0.1——或者 10 的其它任何次负幂—— 精确表示为一个长度有限的二进制小数 解决该问题的一种方式是使用某种整数类型,例如 int 或 long,并且以分为单 位来执行计算。如果你采纳了此路线,请确保该整数类型大到足够表示在程序中 你将要用到的所有值。对这里举例的谜题来说,int 就足够了。下面是我们用 int 类型来以分为单位表示货币值后重写的 println 语句。这个版本将打印出正确答 案 90 分: System.out.println((200 - 110) + "cents"); 解决该问题的另一种方式是使用执行精确小数运算的 BigDecimal。它还可以通 过 JDBC 与 SQL DECIMAL 类型进行互操作。这里要告诫你一点: 一定要用 BigDecimal(String)构造器,而千万不要用BigDecimal(double)。后一个构造 器将用它的参数的“精确”值来创建一个实例:new BigDecimal(.1)将返回一个 表示 0.100000000000000055511151231257827021181583404541015625 的 BigDecimal。通过正确使用 BigDecimal,程序就可以打印出我们所期望的结果 0.90: import java.math.BigDecimal; public class Change1{ } 这个版本并不是十分地完美,因为 Java 并没有为 BigDecimal 提供任何语言上的 支持。使用 BigDecimal 的计算很有可能比那些使用原始类型的计算要慢一些, 对某些大量使用小数计算的程序来说,这可能会成为问题,而对大多数程序来说, 这显得一点也不重要。 public static void main(String args[]){ } System.out.println(new BigDecimal("2.00"). subtract(new BigDecimal("1.10"))); 总之, 在需要精确答案的地方,要避免使用float和double;对于货币计算, 要使用int、long或BigDecimal。对于语言设计者来说,应该考虑对小数运算 提供语言支持。一种方式是提供对操作符重载的有限支持,以使得运算符可以被 塑造为能够对数值引用类型起作用,例如 BigDecimal。另一种方式是提供原始 的小数类型,就像 COBOL 与 PL/I 所作的一样。 谜题 3:长整除 这个谜题之所以被称为长整除是因为它所涉及的程序是有关两个 long 型数值整 除的。被除数表示的是一天里的微秒数;而除数表示的是一天里的毫秒数。这个 程序会打印出什么呢? public class LongDivision{ 3
分享到:
收藏