Java编程思想(第3版)
作者 : (美) Bruce Eckel
译者 : 陈昊鹏 饶若楠 等
丛书名 : 计算机科学丛书
出版日期 : 2005-05-12
ISBN : 7-111-16220-X
定价 : 95.00元
教辅资源下载
扩展信息
语种 : 简体中文
页数 : 756
开本 : 16开
原书名 : Thinking in Java, Third Edition
原出版社: Pearson Education Asia Limited
属性分类: 教材
包含CD :
绝版 :
图书简介

从本书获得的各项大奖以及来自世界各地的读者评论中,不难看出这是一本经典之作。本书作者有多年的教学经验,对C、C++、Java语言都有独到、深入的理解。因此他非常了解如何教授Java语言这门课程,也非常明白语言教学中的难点及人们的困惑。作者以通俗易懂及小而直接的示例解释了一个个晦涩抽象的概念,精心选取“对读者理解Java语言来说最为重要”的部分编写成书。同时又在随书光盘中提供了大量参考材料—这也是本书绝对物超所值的地方。
  随书光盘没有包含本书的源代码(可以从支持网站www.MindView.net免费下载),而是提供了大量作者讲授的讨论课内容及本书的前2版内容。
  本书内容丰富—从Java的基础语法到最高级特性,适合各层次的Java程序员阅读,同时也是高等院校讲授面向对象程序设计语言及Java语言的绝佳教材。

图书特色

图书前言

“上帝赋予人类说话的能力,而言语又创造了思想,思想是人类对宇宙的量度。”
—摘自《Prometheus Unbound》,Shelley
  人类……极其受那些已经成为社会表达工具的特定语言的支配。想像一下,如果一个人可以不使用语言就能够从本质上适应现实世界,语言仅仅是解决具体的交流和反映问题时偶尔才用到的方式,我们会发现,这只能是一种幻想。事实上,“真实世界”在很大程度上是不知不觉地基于群体的语言习惯形成的。
—摘自《The Status of Linguistics As A Science》,1929, Edward Sapir
  如同任何人类语言一样,Java提供了一种表达概念的方式。如果使用得当,随着问题变得更庞大更复杂,这种表达工具将会比别的可供选择的语言更为简单、灵活。
  我们不应该将Java仅仅看作是一些特性的集合——有一些特性在孤立状态下没有任何意义。只有在考虑到设计,而不仅仅是编码时,才能完整地运用Java的各部分。而且,要按照这种方式来理解Java,必须理解它所涉及的问题以及在程序设计时所通常伴随的问题。这本书讨论的是编程问题,它们为什么成为问题,以及Java已经采取什么样的方案来解决它们。因此,每章所阐述的特性集,都是基于我所看到的这一语言在解决特定类型问题时的方式。按照这种方式,我希望能够每次引导读者前进一点,直到Java思想意识成为你最自然不过的语言。
  自始至终,我一直持这样的观点:你需要在头脑中创建一个模型,以加强对这种语言的深入理解;如果你遇到了疑问,就将它反馈到头脑中的模型并推断出答案。

前提条件
  本书假定你对程序设计有一定程度的熟悉:你已经知道程序是一些语句的集合,知 道子程序/函数/宏的概念,知道像“if”这样的控制语句和像“while”这样的循环结构,等等。不过,你可能在许多地方已经学到过这些,例如使用宏语言进行程序设计,或者使用像Perl这样的工具工作。只要你已经达到能够自如地运用程序设计基本思想的程度,你就能够顺利阅读本书。当然,本书对C程序员来说更容易,对于C++程序员更是如此,因此,即使你没有实践过这两种语言,也不要否定自己—而应该更加努力学习(并且,本书附带的多媒体光盘能够带领你快速学习所必需的Java基础知识)。不过,我还会介绍面向对象(OOP)的概念和Java的基本控制机制。
  尽管本书经常引用、参考C和C++语言的特性,但这并不是打算让它们成为内部注释,而是要帮助所有的程序员正确看待这些语言,毕竟Java是从这些语言衍生而来的。我会努力简化这些引用、参考,并且对那些我认为一个非C/C++程序员可能不太熟悉的地方加以解释。

学习Java
  大概在我的第一本书《Using C++》(Osborne/McGraw-Hill,1989)出版发行的同一时候,我就开始教授这种语言了。讲授程序设计语言已经成为我的职业了;自1987年以来,我在世界各地的听众中看到,有的昏昏欲睡,有的面无表情,有的表情迷茫。当我开始给一些小团体进行室内培训时,在这些实践中我发现了一些事情。即使那些面带微笑频频点头的人也对很多问题心存困惑。我发现,多年来在软件开发会议上由我主持的C++分组讨论会(后来变成Java分组讨论会)中,我和其他的演讲者往往是在极短的时间内告诉听众许多话题。因此,最后由于听众的水平不同和讲授教材的方式这两方面的原因,我可能最终会失去一部分听众。可能这样要求得太多了,但因为我是传统演讲的反对者之一(而且对于大多数人来说,我相信这种抵制是因为厌倦),因此我想尽力让每个人都可以跟得上演讲的进度。
  我曾经一度在相当短的时间内做了一系列不同的演讲。因此,我结束了“实践和迭代”(一项在Java程序设计中也得到很好运用的技术)的学习。最后,我根据自己在教学实践中学到的东西发展出一门课程。它以离散的、易消化的步骤以及亲身参与的讨论课(seminar)的形式(最理想的学习形式)解决学习问题,并且每一小节课之后都有一些练习。我的公司—MindView有限公司现在提供公开的室内“Thinking in Java”讨论课;这是我们主要的初级讨论课,为以后更高级的讨论课提供基础。读者可以到网站www.MindView.net上了解详细情况。(初级讨论课在“Hands-On Java”光盘上也能找到。上述网站也可以找到相关信息。)
从每个讨论课获得的反馈信息都可以帮助我去修改和重新制定课程教材,直到我认为它能够成为一个良性运转的教学工具为止。不过不能将本书视为一般的讨论课笔记;我努力在本书中放入尽可能多的信息,并且合理地组织本书结构,从而引导读者顺利进入下一主题。最重要的是,本书面向那些孤军奋战一门新的程序设计语言的读者。

目标
  就像我前一本书《Thinking in C++》那样,这本书是围绕着程序设计语言的教学过程而构建的。具体地说,我的目的是要建立一套机制,提供一种在自己的讨论课中进行程序语言教学的方式。当我思索书中的一章时,我思索的是如何在讨论课上教好一堂课。我的目标是,精选出可以在合理学时内讲完的篇章,随后是适合在课堂上完成的练习作业。

在这本书中我想达到的目标是:
  1) 每一次只演示一个步骤的材料,以便读者在继续后面的学习之前可以很容易地消化吸收每一个概念。
  2) 使用的示例尽可能简单、短小。这样做有时会妨碍我们解决“真实世界”的问题,但是,我发现对于初学者,能够理解例子的每一个细节,而不是理解它所能够解决的问题范畴,前者通常更能为他们带来愉悦。同样,适合在教室内学习的代码数量也有严格限制。正因为如此,我将毫无疑问地会遭到批评—批评我使用“玩具般的示例”,但是我乐意接受那些有利于为教育带来益处的种种事物。
  3) 谨慎安排、呈现特性的先后顺序,以便读者循序渐进,在学习应用某一主题之前已经先接触过它。当然,不可能总是这样;在这种情况下,将会给出简洁的介绍性描述。
  4) 向读者提供“我认为对理解这种程序设计语言来说很重要”的部分,而不是提供我所知道的所有事情。我相信信息在重要性上存在层次差别,有一些事实对于95%的程序员来说永远不必知道—那些只会困扰他们并且使他们对程序复杂性平添许多感触。举一个C语言的例子,如果能够记住操作符优先表(我从未记住过),那么可以写出灵巧的代码。但是你要再想一想,这样做会给读者/维护者带来困惑。因此忘掉优先权,在不是很清楚的时候使用圆括号就行了。
  5) 使每部分的重点足够明确,以便缩短教学和练习之间的时间。这样做不仅使听众在亲身参与讨论课时思维更为活跃和集中,而且还可以让读者更具有成就感。
  6) 给读者打下坚实的基础,使读者能够充分理解问题,以便转入更难的课程学习和书籍阅读中。

JDK的HTML文档
  Sun公司的Java语言及其类库(可以从java.sun.com免费下载)配套提供了电子版文档,可使用Web浏览器阅读。并且,实际上每个厂商开发的Java编译器都有这样的文档系统。大部分出版的Java书籍中也都有这份文档的备份。你可能已经拥有了它,或者能够下载;所以除非必要,本书不会再重复那份文档。因为一般来说,用Web浏览器查找类的描述比在书中查找要快得多(并且在线文档更能保持更新)。你仅需要参考“JDK文档”。只有当需要对文档进行补充,以便你能够理解特定实例时,本书才会提供有关类的一些附加说明。

章节设计
  本书设计时贯穿了一个思想:人们学习Java语言的方式。讨论课听众的反馈帮助我知道了哪些部分是困难的,需要解释清楚。对那些我突然雄心勃勃地想一次介绍很多特性的地方,我渐渐明白(贯穿讲述材料的过程中),如果涉及许多新特性,你就需要对它们全部解释清楚,不然这会很容易使学生感到困惑。因此,我尽量一次少介绍一些特性。
  因此,本书的目标是每一章只讲述一个特性,或者是一小组相关特性,而且它们不必依赖于其他还没有讲述过的特性。这样,你在学习下一特性之前就可以消化当前知识背景中的每个部分。
  下面是对本书所含章节的简单描述,它们与我在“Thinking in Java”讨论课上的授课和练习时段相对应。

第1章:对象导论
  (相应的讲座在光盘上。)这一章是对面向对象程序设计(OOP)的一个综述,包括对“什么是对象”这种基本问题的回答,并介绍了接口与实现、抽象与封装、消息与函数、继承与组合以及非常重要的多态概念。读者还可以大致了解对象的生成问题,例如构造器,对象存活于什么地方,一旦创建好放在什么地方,以及神奇的垃圾回收器(清除那些不再需要的对象)。还会介绍其他一些问题,包括通过异常进行错误处理,响应用户接口的多线程以及联网和Internet。读者将会知道使Java如此特别以及它为什么如此成功的原因。
  第2章:一切都是对象
(相应的讲座在光盘上。)该章将引导你编写自己的第一个Java程序。该章开始先综述一些基本要素:对象引用的概念;基本数据类型和数组简介;对象的生存空间以及垃圾回收器清理对象的方式;怎样将Java中的所有东西归为一种新的数据类型(类);创建自己的类的基本要素;方法、参数以及返回值;名字可见性及从其他类库使用组件;static关键字;以及注释和内嵌文档。
  第3章:控制程序流程
(相应的一系列讲座在“Thinking in C”光盘上。)该章以讲述Java引自C / C++的所有运算符开始。另外,你会看到运算符的共同缺点、类型转换、类型的提升以及优先权。接着介绍基本的控制流程图以及选择操作,这实际上是任何程序设计语言都具有的特性:if-else选择结构;for和while循环结构;用break和continue退出循环,Java的带标签的break和带标签的continue(这说明在Java中没有“goto”);以及switch分支选择。尽管材料大部分具有C 和C++代码的相同思路,但还是存在一些不同之处。
  第4章:初始化与清理
(相应的讲座在光盘上。)该章首先介绍构造器,它用来确保正确的初始化。构造器的定义引出方法重载的概念(因为你可能同时需要几个构造器)。随后讨论的是清理过程,它并非总是如想像般那么简单。通常,当你不再使用一个对象时,可以不必管它,垃圾回收器会最终介入并释放对象占据的内存。这部分详细探讨了垃圾回收器以及它的一些特性。该章最后将更仔细地观察初始化过程:自动成员初始化,指定成员初始化,初始化的顺序,static(静态)初始化以及数组初始化等。
  第5章:隐藏具体实现
(相应的讲座在光盘上。)该章探讨程序代码被包装到一起的方式,以及为什么类库的某些部分是暴露的,而有些部分则是隐藏的。首先要讨论的是package和import关键字,它们执行文件级的包装操作,并允许你构造类库。然后探讨目录路径和文件名的问题。该章最后部分讨论public、private以及protected关键字,以及包内访问的概念及在不同场合下使用不同访问控制级别的意义。
  第6章:复用类
(相应的讲座在光盘上。)复用类的最简单方法是通过组合将对象嵌入到新类中。不过,组合不是从已有的类产生新类的唯一方式。继承这个概念几乎是所有OOP语言的标准,它是对已有的类加以利用,并为其添加新功能的一种方式(也可以是修改它,这是第7章的主题)。继承常常用于代码的复用,方法是保留相同的“基类”,然后在某处补上内容以产生你所期望的类型。该章讲解在Java中组合和继承是怎样重用代码的,以及如何具体运用它们。
  第7章:多态
(相应的讲座在光盘上。)如果仅靠自己,你可能要花上9个月的时间才能发现和理解多态,多态是OOP的基石。通过一些小的、简单的例子,你将会看到如何用继承来创建一族类型,并通过它们共有的基类对该族类型中的对象进行操作。Java的多态可以让你同等地对待同一族中的所有对象,这意味着你编写的大部分代码不必依赖特定的类型信息。这使你的代码更具灵活性,因此,程序的构建和源代码的维护可以变得更为简单,花费也更少。
  第8章:接口与内部类
Java提供了专门的工具来建立设计和重用关系:接口,它是对象接口的纯粹抽象。interface不仅是一个达到极致的抽象类,而且由于它允许你通过创建某个可以向上转型到多个基类型的类,而实现了类似于C++“多重继承”的变体。
首先,内部类看起来似乎是一种简单的程序代码隐藏机制—你只需将类放置到其他类中。不过你将会了解到,内部类不仅仅是起这个作用,它可以知晓外围类并能与之通信。你用内部类编写的这种代码更优雅、更清晰。不过,它是一个全新的概念,需要花费一些时间才能习惯于用内部类进行设计。
  第9章:通过异常处理错误
Java的基本设计哲学是结构不佳的代码将不能运行。编译器会尽可能地去捕获问题,但有时某一问题只能在运行时才被监测到和处理,这个问题可能是程序员错误,也可能是在正常执行程序的情形下自然发生的错误。Java具有异常处理机制,用来处理程序运行时产生的任何问题。该章将解释try、catch、throw、throws以及finally等关键字在Java中是怎样使用的,什么时刻应当抛出异常,以及在捕获到它们时应该做些什么。另外,你还会看到Java的标准异常,如何创建自己的异常,构造器中的异常是什么情况,以及异常期间如何找出异常处理器。
  第10章:类型检查
当你仅有对基类型对象的引用时,Java运行时类型识别(RTTI)能让你找出这一对象的确切类型。通常,你希望有意识地忽略对象的确切类型,以便让Java的动态绑定机制(多态)能够为该类型实现恰当的行为。但有时候,当你仅有对某一对象的基类引用时,能够知道该对象的确切类型则很有帮助。通常这些信息可以让你更有效地执行某些特例操作。该章还将介绍Java的反射机制。你将会学习RTTI 和反射是什么,它们是如何使用的,以及当不再需要RTTI时如何避免它。
  第11章:对象的集合
一个程序如果只拥有固定数量的对象,并且这些对象的存在时间也是明确的,那么这个程序只会是一个非常简单的程序。但是通常情况下,你的程序总会在不同的时刻创建出一些新的对象,而具体是什么时候只有在程序运行时才会知道。此外,除非进入运行期,否则你无法知道所需要的对象数量,以及它们的确切类型。为了解决这个常见的程序设计问题,我们需要能够在任何时间、任何地点创建任何数量的对象。该章将深入探讨Java所提供的集合库:从简单的数组到复杂的容器(数据结构),如ArrayList和HashMap;以便你在使用对象时可以保存它们。
  第12章:Java I/O系统
理论上说,可以将任何程序分成三部分:输入、处理和输出。这意味着I/O(输入/输出)是程序非常重要的一部分。在这一章,你将学到Java所提供的各种I/O类,这些类用于读写文件、内存块以及控制台等。Java I/O框架的演变以及JDK 1.4 的新I/O (nio) 也会阐述。此外,该章还展示了如何获取一个对象,如何对其进行“流化”操作(以便对象可以写入磁盘或通过网络传送),以及如何将其重新构造。Java的对象序列化将会为你实现这一切。另外,还将讨论Java的压缩库—用在Java归档文件格式(JAR)中。最后,阐述新的存储用户特定设置的应用程序接口(Preferences API)和正则表达式。
  第13章:并发
Java提供了一套内置机制,用以支持多个称为“线程”的并发子任务(这些线程均在单一程序内运行)。(除非你的机器里安装了多个处理器,否则这将是多个子任务的唯一表现形式。)尽管线程可以应用在任何地方,但它大多是应用于创建一个反应灵敏的用户界面的情况,举例来说,当某些任务正在执行时,用户仍然可以毫无阻碍地按下按钮或者输入数据。该章会为你打下并行程序设计的坚实基础。
  第14章:创建窗口与applet程序
Java配套提供了Swing GUI 类库,它是一系列类的集合,能以一种轻便形式处理窗口。窗口化程序既可以是万维网applet,也可以是独立的应用程序。该章将介绍用Swing创建程序;还展示了applet签名和 Java Web Start;同时还将介绍重要的JavaBeans技术,它是创建“快速应用程序开发”(RAD)工具的基础。
  第15章:发现问题
程序设计语言检测机制只能让你尽量开发出正确运行的程序。该章介绍一些工具,它们用来解决一些编译器不能解决的问题。其中向前迈出的最大一步是结合了自动单元测试。对于本书,开发了一个自定义的测试系统来确保程序输出的正确性,而且还介绍了一个事实标准—JUnit测试系统。使用开放源码的标准工具Ant实现了自动构建;并且对于团队开发,阐述了CVS的基本要素。对于运行时的问题报送,该章介绍了Java断言机制(这里演示的是结合“按契约设计”概念来使用)、日志记录API、调试器、剖析器以及doclet(这些用来帮助发现源代码中的问题)。
  第16章: 分析与设计
面向对象的模式是一种用于程序设计的崭新的思想方式,而且很多人在开始学习怎样开发OOP项目时都会遇到问题。一旦理解了对象这个概念,而且随着你学会按照面向对象的方式更深入地思考,你就能够充分利用OOP提供的优势创建“好的”设计。该章介绍了分析和设计的思想,以及一些解决问题的方法,利用它们可以在合理时间内开发出好的面向对象程序。该章的主题包括:UML图及相关方法论、用例、类—职责—合作(CRC)卡片、迭代开发、极限编程(XP)、开发和发展可重用代码的方式,以及向面向对象程序设计过渡(转化)的策略。
  附录A:对象的传递与返回
由于在Java中我们和对象会话的唯一方式是通过引用,所以将对象传递给方法以及将对象从方法返回的概念就有一些有趣的结果。此附录说明当你要进入和离开方法时该怎样控制对象;并且还演示了String类,说明了它是如何以另外一种方式来解决问题的。
  附录B:Java编程指南
这个附录包含了我这几年发现和收集到的一些建议,当你进行低层的程序设计和编写代码时,它们能够引导帮助你。
  附录C:补充材料
以下是一些可从MindView处得到的附加学习材料:
  1) 随书光盘。包含“Foundations for Java”讨论课CD,这让你为学习本书做好准备。
  2) “Hands-On Java”光盘的第3版。可以从www.MindView.net网站获取,它是一张基于本书资料的讨论课CD。
  3) Think in Java Seminar。MindView公司提供的、基于本书资料的、主要的入门讨论课。其日程安排和注册页面请参见www.MindView.net。
  4)《Thinking in Enterprise Java》。一本介绍了更高级Java主题的书,适用于企业级程序设计。可以从www.MindView.net网站获得。
  5) J2EE Seminar。向你介绍真实世界的、支持Web的实际开发,以及Java的分布式应用开发。参见www.MindView.net。
  6) Designing Objects & Systems Seminar。介绍面向对象的分析、设计及技术实现。参见www.MindView.net。
  7) 《Thinking in Patterns(with Java)》。该书介绍一些设计模式和问题解决技术,涉及更高级的Java主题。可以从www.MindView.net网站获得。
  8) Thinking in Patterns Seminar。一个基于上述书籍的生动的讨论课。其日程安排和注册页面请参见www.MindView.net。
  9) Design Consulting and Reviews(设计咨询和评审)。协助你保证项目处于良好状态。
  附录D:资源
列出一系列我觉得特别有用的Java书籍。

练习
  在讨论课上,我发现一些简单的练习非常利于学生们理解掌握有关概念,因此在每一章的最后都安排了一些习题。
  大多数练习设计得都很简单,可以让学生在课堂上在合理的时间内完成这些作业,以便指导老师检查辅导以确保所有的学生都吸收了教材的内容。有一些题目具有挑战性,但并没有难度很高的题目。(我想,你应该自己找些这样的题目—或者更有可能的是它们会自动找上门来。)
  一些经过挑选的练习答案可以在名为“The Thinking in Java Annotated Solution Guide”的电子文档中找到,仅需少许费用便可以从www.BruceEckel.com下载得到。

随书光盘
  本书配套提供的还有一张光盘(CD)。过去我一直反对将光盘附在书中,因为我感觉让读者支付一些额外费用去获取几千字节的源代码不太公平,我更喜欢让人们到我的网站下载这些东西。不过,本书这张光盘有一些不同之处。
  这张CD不包含本书的源代码,而是提供了到www.MindView.net网站的超链接(并不需要链接CD上的地址来获取代码,只要直接到那个网站去找寻即可)。这样做的原因是:在CD送往印刷厂时,源代码还不完整,并且这种方式可以使代码在出现问题的任何时候都能及时得到完善和修正。
  因为本书的三个版本之间有非常显著的变化,所以这张CD包含了HTML格式的本书的第1版和第2版(英文版),包括因前述理由而在较新的版本中被移除的、但是在某些情况下对你可能还有用的章节。另外,你可以从www.MindView.net下载本书当前版(第3版)的HTML版本,而且这种版本中还包含了已发现并被订正了的修订。HTML版本的一个好处是它的索引是超链接的,所以对它的内容进行导航要简单得多。
  400多兆字节的CD还包含了完整的“Foundations for Java”多媒体教程。它包括了“Thinking in C”讨论课(介绍了一些Java所沿用的C语言的语法、操作符及函数)。此外,还包括源自我所开创并讲授的“Hands-On Java”讨论课CD第2版前7讲的内容。尽管完整的“Hands-On Java”CD曾经只单独出售(第3版本的“Hands-On Java”CD也是这样,也许你读到这里时它已是可以获得的了—请看 www.MindView.net网站),我之所以决定仅包含第2版的前7讲是因为它们和该书的第3版相比没有太大变化,因此它不仅可以向你提供这本书的基础,而且我还希望通过它让你感受到“Hands-On Java”CD(第3版)的质量和价值。
  我原本打算让Chuck Allison把作为讨论课CD ROM一部分的“Thinking in C”创建成一个独立产品,不过我还是决定将它和第2版本的《Thinking in C++》和《Thinking in Java》包含在一起,这样做是为了让参加讨论课的、没有太多C语言基本语法背景的人们能够很方便地找到相关资料。应该抛开这种思想:“我是一个聪明的程序员,我不想学习C,而想学习C++或Java,因此我会跳过C直接到C++/Java。”在到了讨论课上后,这些人渐渐明白,很好地理解C语言语法这个先决条件很必要。通过本书配套光盘,我们相信每个参加讨论课的人都能事先做好充分准备。
  这张CD也让这本书获得了更多的读者。尽管书中第3章没有介绍Java继承自C的基本部分,但是这张CD中却有很好的介绍,而且它要求学生所具备的程序设计背景比这本书要求的还要少。并且,通过“Hands-On Java”CD第2版中相应的演讲来贯通前7章的资料,应该可以帮助你在进入Java学习之前打下更扎实的基础。这张CD也期望更多的人能够加入Java程序设计的大军。只有从网站www.BruceEckel.com直接订购才能获得“Hands-On Java”CD ROM第3版。

源代码
  本书的所有源代码都能以保留版权的免费软件的形式得到,它们是以单一包的形式发布的,访问www.BruceEckel.com网站便可获取。为了确保你获得的是最新版本,这个发布这些源代码和本书电子版的网站是一个官方网站。你也可以在其他站点上找到这本电子书和这些代码的镜像版本(有一些站点已经在www.BruceEckel.com列出),不过你应该登录这个官方网站确认,以确保镜像版本确实是最新的版本。你可以在课堂或其他教育场所发布这些代码。
  保留版权的主要目的是为了确保源代码能够被正确地引用,并且防止在未经许可的情况下,在出版媒体中重新发布这些代码。(只要说明是引用了这些代码,那么在大多数媒介中使用本书中的示例通常不是问题。)
在每个源码文件中,都包含下述版权声明文字:
This computer source code is Copyright * 2003 MindView, Inc.All Rights Reserved.
Permission to use, copy, modify, and distribute this computer source code (Source Code) and its documentation without fee and without a written agreement for the purposes set forth below is hereby granted, provided that the above copyright notice, this paragraph and the following five numbered paragraphs appear in all copies.

1. Permission is granted to compile the Source Code and to include the compiled code, in executable format only, in personal and commercial software programs.

2. Permission is granted to use the Source Code without modification in classroom situations, including in presentation materials, provided that the book "Thinking in Java" is cited as the origin.

3. Permission to incorporate the Source Code into printed media may be obtained by contacting
MindView, Inc. 5343 Valle Vista La Mesa, California 91941 Wayne@MindView.net

4. The Source Code and documentation are copyrighted by MindView, Inc. The Source code is provided without express or implied warranty of any kind, including any implied warranty of merchantability, fitness for a particular purpose or non-infringement. MindView, Inc. does not warrant that the operation of any program that includes the Source Code will be uninterrupted or error- free. MindView, Inc. makes no representation about the suitability of the Source Code or of any software that includes the Source Code for any purpose. The entire risk as to the quality and performance of any program that includes the Source code is with the user of the Source Code. The user understands that the Source Code was developed for research and instructional purposes and is advised not to rely exclusively for any reason on the Source Code or any program that includes the Source Code. Should the Source Code or any resulting software prove defective, the user assumes the cost of all necessary servicing, repair, or correction.

5. IN NO EVENT SHALL MINDVIEW, INC., OR ITS PUBLISHER BE LIABLE TO ANY PARTY UNDER ANY LEGAL THEORY FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR ANY OTHER PECUNIARY LOSS, OR FOR PERSONAL INJURIES, ARISING OUT OF THE USE OF THIS SOURCE CODE AND ITS DOCUMENTATION, OR ARISING OUT OF THE INABILITY TO USE ANY RESULTING PROGRAM, EVEN IF MINDVIEW, INC., OR ITS PUBLISHER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. MINDVIEW, INC. SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOURCE CODE AND DOCUMENTATION PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, WITHOUT ANY ACCOMPANYING SERVICES FROM MINDVIEW, INC., AND MINDVIEW, INC. HAS NO OBLIGATIONS TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

Please note that MindView, Inc. maintains a web site which is the sole distribution point for electronic copies of the Source Code, http://www.BruceEckel.com (and official mirror sites), where it is freely available under the terms stated above.

If you think you've found an error in the Source Code, please submit a correction using the URL marked "feedback" in the electronic version of the book, nearest the error you've found.
  你可以在自己的项目中引用这些代码,也可以在课堂上引用它们(包括你的演示材料),只要保留每个源文件中出现的保留版权声明即可。

格式说明
  在本书的正文中,标识符(方法、变量和类名)排为粗体。大多数关键字也排为粗体,但是不包括那些频繁使用的关键字,例如“class”,因为如果将它们也设为粗体会令人十分厌烦。
  对于本书中的示例,我使用了一种特定的编码格式,此格式遵循Sun自己在所有代码中实际使用的格式,在它的网站上你会发现这些代码(见java.sun.com/docs/codeconv/index.html),并且似乎大多数Java开发环境都支持这种格式。如果你已经读过我的其他著作,你会注意到Sun的编码格式与我的一致—尽管这与我没什么关系,但我还是很高兴。对代码进行格式化这个议题常常会招致几个小时的热烈争论,因此我不会试图通过自己的示例来规定正确的格式;我对自己使用的格式有自己的想法。因为Java是一种自由形式的程序设计语言,所以你可以继续使用自己喜欢的格式。
  本书中的程序都直接来自于编译过的文件,通过文本处理器以文本形式呈现。因此,本书打印出的代码文件全部都能够运行,而且无编译错误。那些会引起编译错误消息的错误已经用//!注释掉了,所以很容易使用自动方法发现并测试它们。那些被发现并被报送给作者的错误将首先出现在发布的源代码中,并随后出现在本书的更新材料中(还会在网站www.BruceEckel.com上出现)。

Java版本
  在判断代码行为是否正确时,我通常以Sun公司的Java实现为参考。
  这本书重点关注Java 2与JDK 1.4,并使用它们进行测试。如果你需要学习本书这一版中没有讨论的Java语言的先前版本,可以从网站www.BruceEckel.com自由下载本书的第1版和第2版,它们也被包含在本书附带光盘中。

错误
  无论作者使用多少技巧去查找错误,但是有些错误还是悄悄地潜藏了起来,并且经常对新读者造成困扰。
  由于机敏的读者所提供的反馈对我很有价值,因此我开发了名为BackTalk的几个版本的反馈系统(该系统使用几种不同的技术,得到了Bill Venners的辅助,并在其他很多人的帮助下得以实现)。在本书的电子版本(可以从www.BruceEckel.com自由下载)中,文中的每个段落都有自己唯一的URL,点击它可以为该特定段落产生一封将你的意见记录到BackTalk系统的邮件。这种方式让我很容易追踪和更新修正错误。如果你发现了任何你确信是错误的东西,请使用BackTalk系统提交错误以及你建议的修正。对你的帮助我将不胜感激。

封面图片的故事
  《Thinking in Java》的封面创作灵感来自于美国的 Arts & Crafts运动。该运动始于世纪之交,并在1900 到1920年间达到顶峰。它起源于英格兰,是对工业革命带来的机器产品和维多利亚时代高度装饰化风格的回应。Arts & Crafts强调简洁设计,而回归自然是其整个运动的核心,注重手工制造及推崇个性化设计,可是它并不回避使用现代工具。这和我们现今的情形有很多相似之处:世纪之交,从计算机革命的最初起源到对个人来说更精简、更意味深长的事物的演变,以及对软件开发技能而不仅是生产程序代码的强调。
  我以同样的眼光看待Java:尝试将程序员从操作系统机制中解放出来,朝着“软件艺师”的方向发展。
  我和封面设计者自孩提时代就是朋友,我们从这次运动中获得灵感,并且都拥有源自那个时期的(或受那个时期启发而创作的)家具、台灯和其他作品。
  这个封面暗示的另一主题是一个收集盒,博物学家可以用它来展示他们保存的昆虫标本。这些昆虫可以看作是对象,并放置到“盒”这个对象当中,而盒对象又放置到“封面对象”当中,这形象地说明了面向对象程序设计中最为基本的“集合”概念。当然,程序员可能会不禁联想到“程序臭虫(bug)”;这些虫子被捕获,并假设在标本罐中被杀死,最后禁闭于一个展示盒中,似乎暗示Java有能力发现、显示和制服程序臭虫(事实上,这也是它最为强大的属性之一)。

致谢
  首先感谢和我一起开讨论课、提供咨询和开发教学计划的这些合作者:Andrea Provaglio、Dave Bartlett、Bill Venners、Chuck Allison、Jeremy Meyer和 Larry O誃rien。在我转而不停地竭力为那些像我们一样的独立人群开发在一起协同工作的最佳模式的时候,你们的耐心让我感激不已。
  最近,无疑是因为有了Internet,我可以和极其众多的人一起合作,他们协助我一起努力,他们通常是在家办公。过去,我可能必须为这些人提供相当大的办公空间,不过由于现在有了网络、传真以及偶尔打打的电话,我不需要额外的开销就可以从他们的帮助中受益。在我尽力学习更好地与其他人相处的过程中,你们都对我很有帮助,并且我希望继续学习怎样使我的工作能够通过借鉴他人的成果而变得更出色。Paula Steuer在接管我偶尔的商务活动时发挥了不可估量的价值,他使它们变得井井有条(Paula,感谢你在我懈怠时对我的鞭笞)。Jonathan Wilcox, Esq.详细审视了我公司的组织结构,推翻了每一块可能隐藏祸害的石头,并且使所有事情都条理化和合法化了,这让我们心服口服。感谢你的细心和耐心。Sharlynn Cobaugh(她发现了Paula)使自己成为声音处理的专家,她是创建多媒体培训CD ROM和解决其他问题的精英成员之一。感谢你在面临难于处理的计算机问题时的坚定不移。Evan Cofsky(Evan@TheUnixMan.com)已经成为我开发过程中的重要一员,像只鸭子那样沉迷于Python程序设计语言(咳,这样一种混杂的隐喻可能会产生一个臃肿的Python脚本),而且解决了多种难题,包括将BackTalk(最终?)再构造到一个email驱动的XML数据库中。在布拉格Amaio的人们也提出了一些方案来帮助我。Daniel Will-Harris最先受到在网上工作的启发,因此他当然是我所有设计方案的主要人物。
  对于这项工程,我采用了另一个曾在我的头脑中翻腾过一阵的措施。2002年夏天,我在科罗拉多州的Crested Butte创建了一个实习项目,最初找到了两个实习生,而最后项目结束时有5个(有2个志愿者)。他们不仅为本书做出了贡献,而且帮助我专心致志地搞这个项目。感谢JJ Badri、Ben Hindman、Mihajlo Jovanovic、Mark Welsh。Chintan Thakker能够留下并呆到第二个实习期(贯穿本书编写的最后处理过程及其他的工作),因此我必须在Mount Crested Butte租赁实习公寓,我们广招志愿者,最后招到了Mike Levin、Mike Shea和 Ian Phillips,他们都做出了贡献。以后我可能还要再进行其他的实习项目,请访问网站www.MindView.net查看相关消息。
  感谢Doyle Street Cohousing Community(道尔街住房社区)容忍我花了两年的时间来写这本书(并且一直在容忍我所做的一切)。非常感谢Kevin和Sonda Donovan,在我编写本书第1版的夏季里,他们把位于科罗拉多州景色宜人的Crested Butte的住处租给了我(也感谢Kevin为我在CB的住处所做的重新装修)。也感谢Crested Butte友好的居民以及Rocky Mountain Biological Laboratory(岩石山生物实验室),让我有宾至如归的感觉。我在CB的瑜伽老师Maria 和 Brenda,在我编写第3版期间帮助我保持了健康的体魄。
  当老师们来上讨论课时,科罗拉多州Crested Butte的Camp4 Coffee已经成为了标准住所,并且在讨论课中间休息期间,它是我所遇到的最好、最便宜的饮食场所。感谢我的密友Al Smith,是他使这里成为如此好的一个地方,成为Crested Butte培训期间一个如此有趣和愉快的场所。
  感谢Moore Literary Agency的Claudette Moore,因为她无比的耐心和毅力,我才能得到我真正想要的。感谢Prentice Hall的Paul Petralia不断地为我提供我所需要的一切,而且不厌其烦地帮我把所有事情都搞定(并容忍我所有的特殊需求)。
  我的前两本书在Osborne/McGraw-Hill出版时,Jeff Pepper是编辑。Jeff总是在Prentice Hall恰当的地点和恰当的时间出现,他将责任转交给Paul之前,为这些书奠定了最初的根基。感谢你,Jeff。
  感谢Rolf Andr* Klaedtke(瑞士),Martin Vlcek、Vlada和Pavel Lahoda(布拉格),还有 Marco Cantu(意大利),感谢他们在我第一次自行组织的欧洲研讨会巡展中对我的热情款待。
  感谢Gen Kiyooka和他的同事Digigami,他慷慨地为我前几年的网上授课提供了Web服务器。这是无价的辅助学习手段。
  特别感谢Larry 和Tina O誃rien,他们帮助我把我的讨论课制作成了第一版的“Hands-On Java”光盘。(你可以到网站www.BruceEckel.com查看更多消息。)
  在我的开发过程中,有些开放源码的工具已经被证明是无价的;但每次使用它们时都会非常感激它们的创建者。Cygwin (http://www.cygwin.com)为我解决了无数Windows不能解决的问题,并且每天我都会变得更加依赖它(如果在15年前当我的头脑因使用Gnu Emacs而搞得发懵的时候,能有这些该多好啊)。CVS 和Ant已经成为我Java开发过程中必不可少的部分,现在我已经无法再回到不用它们的时代了。我现在甚至已经变得喜欢JUnit了(http://www.junit.org),因为开发人员实际上已经使它成为了“可以运转的最简单的事物。”IBM的 Eclipse (http://www.eclipse.org)对开发社区做出了真正杰出的贡献,并且随着它的不断升级,我期望能看到它的更伟大之处(IBM是怎样成为潮流所向的?我肯定错过了一份备忘录)。Linux在开发过程中每天都要用到,特别对实习生来说尤为如此。当然,如果我在其他地方强调得还不够的话,我得再次重申,我经常使用Python(www.Python.org)解决问题,在我的密友Guido Van Rossum和PythonLabs那些身材臃肿愚笨的天才人物的智慧结晶的基础上,我花费了好几天的时间在Zope 3上进行极限编程(XP)(Tim,我现在已经把你借的鼠标加了个框,正式命名为“TimMouse”)。你们这伙人必须到更健康的地方去吃午餐。(还要感谢整个Python社区,他们是一帮令人吃惊的群体。)
  很多人向我发送修正意见,我感激所有这些人,第1版特别要感谢:Kevin Raulerson(发现无数的程序臭虫),Bob Resendes(简直难以置信),John Pinto、Joe Dante、Joe Sharp(三位都难以置信),David Combs(校正了许多语法和声明),Dr. Robert Stephenson、John Cook、Franklin Chen、Zev Griner、David Karr、Leander A. Stroschein、Steve Clark、Charles A、Lee、Austin Maher、Dennis P. Roth、Roque Oliveira、Douglas Dunn、Dejan Ristic、Neil Galarneau、David B. Malkovsky、Steve Wilkinson以及许许多多的人。本书第1版在欧洲发行时,Marc Meurrens在电子版宣传和制作方面做出了巨大的努力。
  感谢在本书第2版中使用Swing类库帮助我重新编写示例的人们,以及其他助手—Jon Shvarts、Thomas Kirsch、Rahim Adatia、Rajesh Jain、Ravi Manthena、Banu Rajamani、Jens Brandt、Nitin Shivaram、Malcolm Davis,还有所有表示支持的人。
  曾经有许多技术人员走进我的生活,他们后来都和我成了朋友。他们影响了我,他们对我来说是不寻常的,他们平时练习瑜伽功及做一些其他形式的精神训练,我发现这些很有启发性和指导意义。他们是Kraig Brockschmidt、GenKiyooka和Andrea Provaglio(他帮助我了解了Java和程序设计在意大利的概况,现在他在美国,是MindView团队的一员)。
  对Delphi的理解使我更容易理解Java,这一点儿都不奇怪,因为它们有许多概念和语言设计决策是相通的。我的懂Delphi的朋友们给我提供了许多帮助,使我能够洞察一些非凡的编程环境。他们是Marco Cantu(另一个意大利人—难道会说拉丁语的人在学习Java时有得天独厚的优势?)、Neil Rubenking(直到发现喜欢计算机之前,他一直都在做瑜珈/素食/禅道),当然还有Zack Urlocker(Delphi产品经理),他是我游历世界时的好伙伴。
  我的朋友Richard Hale Shaw(以及Kim)的洞察力和支持都很有帮助。Richard和我花了数月时间将教学内容合并到一起,并为参加学习的学生设计出一套完美的学习体验。
  书籍设计、封面设计以及封面照片是由我的朋友Daniel Will-Harris制作的。他是一位著名的作家和设计家(http://www.WillHarris.com),在计算机和桌面排版发明之前,他在初中的时候就常常摆弄刮擦信(rub-on letter),他总是抱怨我的代数含糊不清。然而,要声明的是,是我自己制作的照排好的(camera-ready)页面,所以所有排字错误都应该算到我这里。我是用Microsoft Word XP for Windows来编写这本书的,并使用Adobe Acrobat制作照排页面的。本书是直接从Acrobat PDF文件创建而来的。电子时代给我们带来了厚礼,我恰巧是在海外创作了本书第1版和第2版的最终稿—第1版是在南非的开普敦送出的,而第2版却是在布拉格寄出的。第3版则来自科罗拉多州的Crested Butte。
  特别感谢我的所有老师和我的所有学生(他们也是我的老师),其中最有趣的一位写作老师是Gabrielle Rico(《Writing the Natural Way》一书的作者,Putnam于1983年出版)。我将一直珍藏在Esalen一周所经历的非凡的记忆。
书后面的照片是我爱人Dawn McGee照的,并且是她让我那样笑的。
  曾向我提供过支持的朋友包括(当然还不止他们):Andrew Binstock,SteveSinofsky,JD Hildebrandt,Tom Keffer,Brian McElhinney,Brinkley Barr,《Midnight Engineering》杂志社的Bill Gates,Larry Constantine和Lucy Lockwood,Greg Perry,Dan Putterman,Christi Westphal,Gene Wang,Dave Mayer,David Intersimone,Andrea Rosenfield,Claire Sawyers,另一些意大利朋友(Laura Fallai,Corrado,Ilsa和Cristina Giustozzi),Chris和Laura Strand,Almquists,Brad Jerbic,Marilyn Cvitanic,Mabrys,Haflingers,Pollocks,Peter Vinci,Robbins Families,Moelter Families(和McMillans),Michael Wilk,Dave Stoner,Laurie Adams,Cranstons,Larry Fogg,Mike和Karen Sequeira,Gary Entsminger和Allison Brody,Kevin Donovan和Sonda Eastlack,Chester和Shannon Andersen,Joe Lordi,Dave和Brenda Bartlett,David Lee,Rentschlers,Sudeks,Dick,Patty和Lee Eckel,Lynn和Todd以及他们的家人。当然还有我的爸爸和妈妈。

图书序言

我的兄弟托德正准备从硬件领域转移到程序设计领域,我曾向他建议,下一场技术革命将是基因工程。
  我们将使用微生物来制造食品、燃料和塑料;这些微生物不仅能清除污染,还能让我们以比现在少得多的代价,就能主宰整个物质世界。我曾以为,相比之下计算机革命将显得微不足道。
  后来我意识到自己犯了科幻小说家常犯的错误:纠缠在技术细节上(当然,这在科幻小说里司空见惯)。有经验的作家都知道,故事的重点不是技术,而在于人。基因工程的确将对我们的生活造成深远的影响,但它未必就会使计算机革命(或者至少是信息革命)黯然失色,因为正是计算机技术推动了基因工程的发展。信息指的是人与人之间的沟通。当然,汽车、鞋子,包括基因疗法,这些都很重要,但它们最终都只是表面现象。人类如何与世界相处才是问题的本质。这个相处的过程就是沟通。
  本书恰好就是一个例子。很多人认为我很大胆,或者有点疯狂,因为我把所有资料都放在网络上。“还有谁会购买呢?”他们这样问。如果我的性格保守谨慎一些,我就不会这么做。但是我真的不想再用传统方式来编写一本新的计算机书籍。我不知道这么做会有什么后果,但结果表明,这是我在写书经历中做过的最明智的一件事。
  首先,人们开始把修正意见反馈给我。这是个令人惊叹的过程,因为人们仔细检查每个角落、每个缝隙,找出技术上和文字上的种种问题,让我得以改正所有错误,而这些错误单凭我个人是很难觉察到的。人们对这种做法还有些顾虑,他们常常说“我并无冒犯之意……”,然后扔给我一大堆错误。无疑我自己从未察觉到这些错误。我很喜欢这种集体参与的过程,这也使这本书更加特别。这些反馈很有价值,所以我使用“BackTalk”系统创建了一些应用,来对这些建议进行收集和分类。
  但是,很快我就开始听到“嗯,很好。把书做成电子版放到网络上是个好主意,可是我希望购买印刷出版并装订成册的书籍”。我曾经努力过,让每个人都能很容易地打印出美观的书籍,但这样仍然无法满足人们对印刷书籍的需求。大多数人都不习惯在计算机屏幕上阅读整本书,也不喜欢总是带着一捆捆的纸,所以即使这些打印出来的书籍再美观,也吸引不了他们(而且激光打印机的碳粉并不便宜)。看来即使是计算机革命,也难以抢走出版商的生意。不过,有个学生提出这也许会在未来成为一种出版模式:先在网络上出版书籍,当它引起足够的关注以后,才考虑制作纸质版本。目前,绝大多数书籍都不赚钱,这种新方式或许可以给整个出版业带来更多的利润。
  这本书也以另一种方式带给我一些启迪。开始,我认为Java“只不过是另一种程序设计语言”—从许多方面看的确如此。但随着时间流逝,以及对Java学习的深入,我才开始明白,这个编程语言的目的,与我所见过的其他语言根本不同。
  程序设计就是对复杂度的管理,复杂度包括:待解问题的复杂度和所依赖的底层机器的复杂度。正是因为这种复杂度的存在,导致了大多数项目的失败。并且据我所知,还没有哪个程序设计语言全力将主要设计目标放在“征服程序开发与维护过程中的种种复杂度”上。当然,许多编程语言设计时也确实考虑到了复杂度问题,但它总是与被视为更本质的问题混在一起。当然,那些也都是让程序员感到困扰的问题。比如,C++必须向上兼容于C(为使C程序员容易过渡),并具有执行效率高的优点。这两点都很有用,并且帮助C++取得了成功。不过,两者也引入了额外的复杂度,使得某些项目无法完成。(当然,你可以归咎于开发或管理人员,但如果有某种语言可以帮助我们找到错误,何乐而不为呢?)Visual Basic(VB)是另一个例子,它被局限于Basic语言(它并不把可扩展能力作为设计目标),这就使得所有堆积于VB 之上的扩充功能,都造成了可怕且难以维护的语法。Perl 也向上兼容于Awk、Sed、Grep以及其他Unix工具,这就导致了被诟病为“能写不能读”的程序代码(也就是说,一段时间之后,你就无法看懂这些代码)。另一方面,C++、VB、Perl、Smalltalk 之类的编程语言,在设计上也都为复杂度问题付出了相当大的努力,因而在解决特定类型问题的时候非常成功。
  当我开始理解Java 之后,印象最深的莫过于在Java上体现出的Sun公司的设计目标:为程序员降低复杂度。就好像说:“我们关注的是降低编写健壮代码的困难程度和需要的时间。”以前,编写健壮代码将导致性能降低(尽管有许多这样的承诺—Java总有一天能够执行得足够快),不过Java的确大大缩短了开发时间;相比同等功能的C++ 程序,它只需一半甚至更少的开发时间。只凭这一点,就足以省下大量的时间与金钱。不过,Java 并不仅仅如此。它又不断引入了一些日益重要的复杂任务,比如多线程和网络编程。并且通过语言本身的特性和程序库,使得这些工作变得轻而易举。最后,Java还着眼于某些有着极高复杂度的问题:跨平台程序、动态改变程序代码,甚至安全问题,它们都属于复杂度问题的重要议题。所以尽管存在已知的效率问题,Java 带来的许诺仍极其诱人:它能使程序员的生产率大大提高。
  根据我的观察,Web是Java影响最深远的地方之一。网络程序设计总是非常困难,但Java使之得以简化(Java的设计者仍在努力使之变得更简单)。网络程序设计所关注的,就是研究如何让我们用比使用电话更有效率、更廉价的方式进行沟通(单是电子邮件就已经使许多业务领域发生了革命性的变化)。当我们能更有效地进行沟通时,奇妙的事情就开始发生,这也许要比基因工程可能创造的前景更让人感到神奇。
  编写程序、团队开发、设计用户界面(让程序可以和用户交互)、跨平台执行、轻松编写跨因特网的通信程序等,Java给我们带来的所有这一切扩展了人与人之间的通信带宽。我认为,通信革命的成果也许不应以海量数据的传输来衡量;我们将体会到真正的革命,因为我们能更容易地和他人沟通—可以是一对一的形式,可以是分组形式,也可以是全球通信的形式。有人曾说过,随着足够多的人之间产生了足够多的相互联系,下一次革命将会是一种全球化思维的形成。Java可能是、也可能不是这场革命的导火索,但至少这种可能性是存在的,这使我觉得,教授这门语言是一件非常有意义的事情。

第3版序
  这一版的主要目的和大量工作都用在了与Java 1.4版保持同步上。不过,本书的主旨也更加清楚:使大多数读者通过本书牢牢抓住语言的基本概念,以便深入学习更复杂的主题。因为Java还在不断地演化,所以重新定义“基础知识”的涵义就很有必要,再说本书也不应过于面面俱到。这就意味着,比如,完全重写了“并发”这一章(以前称为“多线程”),它能使读者对线程的核心概念有一个基本的了解。没有这一点,读者就很难理解线程中那些更复杂的概念。
  我还认识到了代码测试的重要性。如果没有内置的测试框架及相应测试用例,并在每次构造系统的时候都进行测试,那么就无法知道代码是否可靠。在本书中,为了做到这一点,专门编写了单元测试框架,用来演示和验证每个程序的输出。这些内容在第15章中介绍,其中还有对ant(Java构建系统的事实标准,与make类似)、JUnit(Java单元测试框架的事实标准)、日志和断言机制(由JDK 1.4新引入),以及对调试和性能分析的介绍。为了涵盖所有这些概念,我把这一章命名为“发现问题”,里面介绍的内容是我认为所有Java程序员都应该掌握的基本技能。
  此外,我复查了书中所有的示例,并同时问自己:“为什么要用这种方法呢?”多数情况下我会做一些修改和润色,这样会使例子更贴切,同时还有助于演示一些我认为比较好的Java编程实践(至少在比较基础的范围内)。此外,我还删除了一些不再有意义的示例,并加入了一些新的示例,许多已有示例也被重新设计和修改过。
  全书分为16章,涵盖了对Java语言的基本介绍,它可以用作基础课程的教材。但那些更高级的主题又该如何处理呢?
  我原计划为本书新加一部分,专门介绍“Java 2企业版”(J2EE)的基础知识。其中许多章由我的朋友及一同授课或开发项目的同事编写,他们是:Andrea Provaglio, Bill Venners, Chuck Allison, Dave Bartlett和Jeremy Meyer。当我把这些新章的进度和出版日期相对照的时候,我就有些担心。并且我注意到,前16章的篇幅就已经与本书第2版的全部篇幅一样大了。而即使是这个篇幅,读者也会经常抱怨说太大了。
  对于本书的前两版,读者给予了极高评价,当然我也十分欣慰。但有时他们也会抱怨。其中常被提及的就是“这本书太厚了”。在我看来,如果这就是你挑出的唯一毛病,那真是令人哭笑不得。(这会让人联想到奥地利国王对莫扎特作品的抱怨:“音符太多了”。我并没有任何与莫扎特相比的意思。)此外,我只能认为发出这种抱怨的人尚未了解Java语言的博大精深,也未见识过其他Java书籍。尽管如此,我还是在这一版中尽量删减掉那些已经过时,或是不那么关键的内容。总之,我仔细检查了所有地方,在第3版中删除了那些不必要的内容,并尽可能做出了修改和润色。这么做我很放心,因为本书的前两个版本还可以从网站(www.BruceEckel.com)免费下载,随书光盘中也有。如果你还需要那些老资料,这些地方都能找到,这样可以使作者减轻很多负担。比如,“设计模式”这一章太大了,我把它改写成了另一本书—《Thinking in Patterns (with Java)》(这也可以从网站上下载)。
  在Java的下一个版本(JDK 1.5)中,预计Sun公司会受C++模板启发而引入泛型这个新的重要主题。我本来已经决定,到时候把本书分为两册,以加入新的内容。但有个声音悄悄在问:“为什么要等呢?”于是,我决定在这一版中就这么做,一切问题也迎刃而解。我正试着往一本介绍性的书籍中塞入很多内容。
  我没有把本书分为两册,而是写成一本新书,包含了一些高级主题,书名叫《Thinking in Enterprise Java》,它也可以从www.BruceEckel.com免费下载。由于是一本单独的书,因此它的篇幅可以随着内容的需要而扩展。与《Thinking in Java》一样,它的目标是向读者提供一本容易理解、涵盖J2EE技术基础知识的入门书,并为读者学习更深入的内容做准备。读者能在附录C中找到更多说明。
  对于那些仍然不能忍受本书篇幅的读者,我只能说声抱歉。不管你是否相信,为了让它尽可能薄,我已经作了很多努力。尽管书较厚,但我认为还有许多替代方式可供你选择。比如,本书有电子版,如果你带着便携式电脑的话,你可以把电子版放进电脑,这样也不会给日常生活带来额外的负担。如果你一定要用纸质版本,我听说有人一次打印一章,然后放在公文包里,在火车上阅读。

Java 2, JDK 1.4
  JDK的发布版本以1.0、1.1、1.2、1.3表示,本书针对1.4版。尽管这些版本号还是“各自独立”的,但JDK 1.2或更高版本的标准说法是“Java 2”。这表明“旧式Java”(我在本书的第1版中讨论了其中的许多缺陷)和Java的改进版本之间存在巨大差异。后者的缺陷要少得多,而且引入了很多优秀的设计。
  本书针对Java 2编写,尤其是JDK 1.4(很多代码不能在以前版本的JDK下编译,如果你试图这么做的话,构建系统将显示出错信息并终止)。本书大刀阔斧地删除了一些过时的内容,并且重写了该语言新引入和改进的部分。那些过时的内容可以在本书的以前版本中找到(也可以通过Web或者本书光盘)。此外,任何人都可以从java.sun.com免费下载JDK,也就是说,本书针对JDK 1.4,不会给任何人带来因升级而造成的经济负担。
  Java的以前版本在Linux系统上发布的速度稍慢(参见www.Linux.org),这个问题正在得到改进,针对Linux的新版本与针对其他平台的版本将同时发布,现在甚至Macintosh也开始能跟上Java的新版本。与Java相互配合,Linux现在正处于非常重要的发展阶段,它正迅速成为市场上最重要的服务器平台,因为它快速、可靠、健壮、安全、易于维护,并且是免费的。这是计算机历史上一场真正的革命,我认为以前的任何工具都没能具备所有这些特征。Java在服务器端编程中占据了重要位置,它采用了Servlet和Java 服务器页面(JSP)技术,这与传统的通用网关接口(CGI)编程相比是一个巨大的进步(相关主题请参考《Thinking in Enterprise Java》)。

译者简介

陈昊鹏 饶若楠 等:暂无简介

译者序

《Java编程思想》已经成为广大Java程序员和爱好者们手中必备的宝典,它在读者心目中的地位已经无可替代。其作者Bruce Eckel也已经成为了众多Java程序员顶礼膜拜的大师。随着Java技术的发展以及对Java认识的不断深入,Bruce Eckel推出了《Java编程思想》第3版。在这里我们应该向他致敬,他不断精益求精、锐意进取的精神正是我们努力学习的榜样。
  随着软件开发技术,尤其是Web应用开发技术的发展,Java越来越受到人们的青睐。越来越多的企业都选择使用Java及其相关技术(例如J2EE技术)来构建它们的应用系统。但是,掌握好Java语言并不是一件可以轻松完成的任务,如何真正掌握Java语言,从而编写出健壮的、高效的、灵活的程序,是Java程序员们面临的重大挑战。
  《Java编程思想》就是一本能够让Java程序员轻松面对这一挑战,并最终取得胜利的经典书籍。本书深入浅出、循序渐进地把我们领入Java的世界,让我们在不知不觉中学会了用Java的思想去考虑问题、解决问题。本书不仅适合Java的初学者,对于有经验的Java程序员来说,每次阅读本书也总能有新的体会,这正是本书的魅力所在。
  本书的第2版由侯捷先生翻译,他已经把翻译原著这项工作做到了极致。我们在翻译过程中总是诚惶诚恐,一方面害怕曲解了原著的意思,另一方面也害怕破坏了第2版译著已经做出的让广大中国读者认可本书的种种努力。
  我们在翻译本书的过程中力求忠于原著,对于书中出现的大量的专业术语尽量遵循标准的译法,并在有可能引起歧义之处著上了英文原文,以方便读者的对照理解。
  全书的翻译由陈昊鹏和饶若楠合作完成,薛翔、郭嘉和方小丽也参与了全书的翻译工作。由于我们水平有限,书中出现错误与不妥之处在所难免,恳请读者批评指正。


陈昊鹏
上海交通大学软件学院

图书目录

第1章  对象导论 1
1.1  抽象过程 1
1.2  每个对象都有一个接口 2
1.3  每个对象都提供服务 4
1.4  被隐藏的具体实现 5
1.5  复用具体实现 5
1.6  继承:复用接口 6
1.7  伴随多态的可互换对象 9
1.8  对象的创建、使用和生命期 12
1.8.1  集合与迭代器 13
1.8.2  单根继承结构 14
1.8.3  向下转型与模板/泛型 15
1.8.4  确保正确清理 15
1.9  异常处理:处理错误 16
1.10  并发性 17
1.11  持久性 17
1.12  Java与Internet 18
1.12.1  Web是什么 18
1.12.2  客户端编程 19
1.12.3  服务器端编程 23
1.12.4  应用 23
1.13  Java为什么成功 24
1.13.1  系统易于表达、易于理解 24
1.13.2  类库的巨大影响力 24
1.13.3  错误处理 24
1.13.4  大型程序设计 24
1.14  Java与C++ 25
1.15  总结 26
第2章  一切都是对象 27
2.1  用引用操纵对象 27
2.2  必须由你创建所有对象 28
2.2.1  存储到什么地方 28
2.2.2  特例:基本类型 29
2.2.3  Java中的数组 30
2.3  永远不需要销毁对象 30
2.3.1  作用域 30
2.3.2  对象的作用域 31
2.4  创建新的数据类型:类 31
2.5  方法、参数和返回值 33
2.6  构建一个Java程序 35
2.6.1  名字可见性 35
2.6.2  运用其他构件 35
2.6.3  static 关键字 36
2.7  你的第一个Java程序 37
2.8  注释和嵌入式文档 39
2.8.1  注释文档 39
2.8.2  语法 39
2.8.3  嵌入式HTML 40
2.8.4  一些标签示例 41
2.8.5  文档示例 42
2.9  编码风格 43
2.10  总结 43
2.11  练习 43
第3章  控制程序流程 45
3.1  使用Java操作符 45
3.1.1  优先级 45
3.1.2  赋值 45
3.1.3  算术操作符 48
3.1.4  自动递增和递减 50
3.1.5  关系操作符 52
3.1.6  逻辑操作符 53
3.1.7  按位操作符 55
3.1.8  移位操作符 56
3.1.9  三元操作符 if-else 59
3.1.10  逗号操作符 60
3.1.11  字符串操作符 + 60
3.1.12  使用操作符时常犯的错误 61
3.1.13  类型转换操作符 61
3.1.14  Java没有“sizeof” 63
3.1.15  再论优先级 63
3.1.16  操作符小结 64
3.2  执行流程控制 73
3.2.1  true和false 73
3.2.2  if-else 73
3.2.3  return 74
3.2.4  迭代 75
3.2.5  do-while 76
3.2.6  for 76
3.2.7  break和 continue 78
3.2.8  switch 83
3.3  总结 86
3.4  练习 86
第4章  初始化与清理 89
4.1  用构造器确保初始化 89
4.2  方法重载 91
4.2.1  区分重载方法 93
4.2.2  涉及基本类型的重载 93
4.2.3  以返回值区分重载方法 98
4.2.4  缺省构造器 98
4.2.5  this关键字 99
4.3  清理:终结处理和垃圾回收 102
4.3.1  finalize()的用途何在 103
4.3.2  你必须实施清理 103
4.3.3  终结条件 104
4.3.4  垃圾回收器如何工作 105
4.4  成员初始化 107
4.4.1  指定初始化 108
4.4.2  构造器初始化 109
4.5  数组初始化 115
4.6  总结 121
4.7  练习 122
第5章  隐藏具体实现 125
5.1  包:程序库单元 125
5.1.1  创建独一无二的包名 127
5.1.2  定制工具库 129
5.1.3  用 import改变行为 130
5.1.4  对使用包的忠告 130
5.2  Java访问权限修饰词 131
5.2.1  包访问权限 131
5.2.2  public:接口访问权限 131
5.2.3  private: 你无法访问 133
5.2.4  protected:继承访问权限 134
5.3  接口和实现 135
5.4  类的访问权限 136
5.5  总结 138
5.6  练习 139
第6章  复用类 141
6.1  组合语法 141
6.2  继承语法 144
6.3  结合使用组合和继承 148
6.3.1  确保正确清理 149
6.3.2  名称屏蔽 152
6.4  在组合与继承之间选择 153
6.5  protected关键字 155
6.6  增量开发 156
6.7  向上转型 156
6.8  final关键字 158
6.8.1  final 数据 158
6.8.2  final 方法 161
6.8.3  final 类 163
6.8.4  有关final的忠告 163
6.9  初始化及类的加载 164
6.10  总结 166
6.11  练习 166
第7章  多态 169
7.1  再论向上转型 169
7.2  转机 172
7.2.1  方法调用绑定 172
7.2.2  产生正确的行为 173
7.2.3  可扩展性 175
7.2.4  缺陷:“覆盖”私有方法 178
7.3  抽象类和抽象方法 179
7.4  构造器和多态 182
7.4.1  构造器的调用顺序 182
7.4.2  继承与清理 184
7.4.3  构造器内部的多态方法的行为 186
7.5  用继承进行设计 188
7.5.1  纯继承与扩展 189
7.5.2  向下转型与运行时类型识别 191
7.6  总结 192
7.7  练习 193
第8章  接口与内部类 195
8.1  接口 195
8.1.1  Java中的多重继承 198
8.1.2  通过继承来扩展接口 200
8.1.3  群组常量 202
8.1.4  初始化接口中的字段 203
8.1.5  嵌套接口 204
8.2  内部类 207
8.2.1  内部类与向上转型 208
8.2.2  在方法和作用域内的内部类 210
8.2.3  匿名内部类 211
8.2.4  链接到外部类 215
8.2.5  嵌套类 216
8.2.6  引用外围类的对象 218
8.2.7  从多层嵌套类中访问外部类的成员 219
8.2.8  内部类的继承 220
8.2.9  内部类可以被覆盖吗 220
8.2.10  局部内部类 222
8.2.11  内部类标识符 223
8.3  为什么需要内部类 224
8.3.1  闭包与回调 226
8.3.2  内部类与控制框架 228
8.4  总结 233
8.5  练习 233
第9章  通过异常处理错误 235
9.1  基本异常 235
9.2  捕获异常 237
9.2.1  try块 237
9.2.2  异常处理程序 237
9.3  创建自定义异常 238
9.4  异常说明 241
9.5  捕获所有异常 242
9.5.1  重新抛出异常 243
9.5.2  异常链 246
9.6  Java标准异常 249
9.7  使用finally进行清理 251
9.7.1  finally用来做什么 252
9.7.2  缺憾:异常丢失 254
9.8  异常的限制 255
9.9  构造器 258
9.10  异常匹配 260
9.11  其他可选方式 261
9.11.1  历史 262
9.11.2  观点 263
9.11.3  把异常传递给控制台 265
9.11.4  把“被检查的异常”转换为“不检查的异常” 265
9.12  异常使用指南 267
9.13  总结 267
9.14  练习 267
第10章  类型检查 269
10.1  为什么需要RTTI 269
10.1.1  Class对象 271
10.1.2  类型转换前先做检查 273
10.2  RTTI语法 282
10.3  反射:运行时的类信息 284
10.4  总结 288
10.5  练习 288
第11章  对象的集合 291
11.1  数组 291
11.1.1  数组是第一级对象 292
11.1.2  返回一个数组 294
11.1.3  Arrays类 296
11.1.4  填充数组 302
11.1.5  复制数组 304
11.1.6  数组的比较 305
11.1.7  数组元素的比较 306
11.1.8  数组排序 308
11.1.9  在已排序的数组中查找 310
11.1.10  对数组的小结 311
11.2  容器简介 311
11.2.1  容器的打印 312
11.2.2  填充容器 313
11.3  容器的缺点:未知类型 319
11.3.1  有时候它也能工作 320
11.3.2  制作一个类型明确的ArrayList 322
11.4  迭代器 323
11.5  容器的分类法 326
11.6  Collection的功能方法 328
11.7  List的功能方法 331
11.7.1  使用LinkedList制作栈 334
11.7.2  使用LinkedList制作队列 335
11.8  Set的功能方法 336
11.9  Map的功能方法 339
11.9.1  SortedMap 343
11.9.2  LinkedHashMap 344
11.9.3  散列法与散列码 345
11.9.4  覆盖hashCode() 353
11.10  持有引用 356
11.11  再论迭代器 360
11.12  选择接口的不同实现 361
11.12.1  对List的选择 361
11.12.2  对Set的选择 364
11.12.3  对Map的选择 366
11.13  List的排序和查询 368
11.14  实用方法 369
11.14.1  设定Collection或Map为不可修改 371
11.14.2  Collection或Map的同步控制 372
11.15  未获支持的操作 373
11.16  Java 1.0/1.1 的容器 375
11.16.1  Vector和Enumeration 375
11.16.2  Hashtable 376
11.16.3  Stack 376
11.16.4  BitSet 377
11.17  总结 378
11.18  练习 379
第12章  Java I/O系统 383
12.1  File类 383
12.1.1  目录列表器 383
12.1.2  目录的检查及创建 386
12.2  输入和输出 388
12.2.1  InputStream类型 389
12.2.2  OutputStream类型 389
12.3  添加属性和有用的接口 390
12.3.1  通过FilterInputStream从Input-Stream读取数据 391
12.3.2  通过FilterOutPutStream向OutputStream写入 391
12.4  Reader和Writer 392
12.4.1  数据的来源和去处 393
12.4.2  更改流的行为 393
12.4.3  未发生变化的类 394
12.5  自我独立的类:RandomAccessFile 394
12.6  I/O流的典型使用方式 395
12.6.1  输入流 397
12.6.2  输出流 398
12.6.3  管道流 399
12.7  文件读写的实用工具 400
12.8  标准I/O 401
12.8.1  从标准输入读取 401
12.8.2  将System.out转换成PrintWriter 402
12.8.3  标准I/O重定向 402
12.9  新I/O 403
12.9.1  转换数据 406
12.9.2  获取基本类型 409
12.9.3  视图缓冲器 411
12.9.4  用缓冲器操纵数据 415
12.9.5  缓冲器的细节 415
12.9.6  存储器映射文件 419
12.9.7  文件加锁 422
12.10  压缩 424
12.10.1  用GZIP进行简单压缩 424
12.10.2  用Zip进行多文件保存 425
12.10.3  Java档案文件 428
12.11  对象序列化 429
12.11.1  寻找类 432
12.11.2  序列化的控制 433
12.11.3  使用“持久性” 440
12.12  Preferences 445
12.13  正则表达式 447
12.13.1  创建正则表达式 447
12.13.2  量词 448
12.13.3  模式和匹配器 449
12.13.4  split() 455
12.13.5  替换操作 456
12.13.6  reset() 458
12.13.7  正则表达式和Java I/O 459
12.13.8  需要StringTokenizer吗 459
12.14  总结 460
12.15  练习 461
第13章  并发 463
13.1  动机 463
13.2  基本线程 464
13.2.1  让步 466
13.2.2  休眠 467
13.2.3  优先权 469
13.2.4  后台线程 471
13.2.5  加入到某个线程 473
13.2.6  编码的变体 475
13.2.7  建立有响应的用户界面 480
13.3  共享受限资源 481
13.3.1  不正确地访问资源 481
13.3.2  资源冲突 484
13.3.3  解决共享资源竞争 486
13.3.4  临界区 491
13.4  线程状态 495
13.5  线程之间的协作 496
13.5.1  等待与通知 496
13.5.2  线程间使用管道进行输入/输出 499
13.5.3  更复杂的协作 501
13.6  死锁 501
13.7  正确的停止方法 504
13.8  中断阻塞线程 505
13.9  线程组 506
13.10  总结 507
13.11 练习 508
第14章  创建窗口与applet程序 511
14.1  applet基础 512
14.1.1  applet的限制 512
14.1.2  applet的优势 513
14.1.3  应用框架 513
14.1.4  在Web浏览器中运行applet 514
14.1.5  使用Appletviewer工具 516
14.1.6  测试applet 516
14.2  从命令行运行applet 517
14.3  创建按钮 520
14.4  捕获事件 520
14.5  文本区域 522
14.6  控制布局 524
14.6.1  BorderLayout 524
14.6.2  FlowLayout 525
14.6.3  GridLayout 525
14.6.4  GridBagLayout 526
14.6.5  绝对定位 526
14.6.6  BoxLayout 526
14.6.7  最好的方式是什么 530
14.7  Swing事件模型 530
14.7.1  事件与监听器的类型 530
14.7.2  跟踪多个事件 535
14.8  Swing组件一览 537
14.8.1  按钮 538
14.8.2  图标 540
14.8.3  工具提示 542
14.8.4  文本域 542
14.8.5  边框 544
14.8.6  滚动面板 545
14.8.7  一个迷你编辑器 547
14.8.8  复选框 548
14.8.9  单选按钮 549
14.8.10  组合框(下拉列表) 550
14.8.11  列表框 551
14.8.12  页签面板 553
14.8.13  消息框 554
14.8.14  菜单 555
14.8.15  弹出式菜单 560
14.8.16  绘图 562
14.8.17  对话框 564
14.8.18  文件对话框 567
14.8.19  Swing组件上的HTML 569
14.8.20  滑块与进度条 570
14.8.21  树 571
14.8.22  表格 573
14.8.23  选择外观 574
14.8.24  剪贴板 576
14.9  把applet打包进JAR文件 578
14.10  为applet签名 579
14.11  JNLP与Java Web Start 583
14.12  编程技术 587
14.12.1  动态绑定事件 587
14.12.2  将业务逻辑与用户界面逻辑相分离 589
14.12.3  规范方式 591
14.13  Swing与并发 591
14.13.1  再论Runnable 591
14.13.2  管理并发 593
14.14  可视化编程与JavaBean 596
14.14.1  JavaBean是什么 597
14.14.2  使用Introspector抽取出BeanInfo 598
14.14.3  一个更复杂的Bean 603
14.14.4  JavaBean与同步 606
14.14.5  把Bean打包 609
14.14.6  对Bean更高级的支持 610
14.14.7  有关Bean的其他读物 611
14.15  总结 611
14.16  练习 611
第15章  发现问题 615
15.1  单元测试 616
15.1.1  一个简单的测试框架 617
15.1.2  JUnit 626
15.2  利用断言提高可靠性 630
15.2.1  断言语法 630
15.2.2  为“按契约设计”使用断言 633
15.2.3  示例:按契约设计+白盒单元测试 635
15.3  用Ant构建 639
15.3.1  使所有事物自动化 639
15.3.2  使用make的问题 640
15.3.3  Ant:事实上的标准 640
15.3.4  用CVS进行版本控制 643
15.3.5  每日构建 645
15.4  日志 645
15.4.1  日志级别 647
15.4.2  LogRecord 649
15.4.3  处理器 650
15.4.4  过滤器 654
15.4.5  格式器 655
15.4.6  例子:发送email报告日志消息 656
15.4.7  通过名字空间控制日志级别 658
15.4.8  大型工程的日志实践 660
15.4.9  小结 662
15.5  调试 663
15.5.1  使用JDB调试 663
15.5.2  图形化调试器 667
15.6  剖析和优化 667
15.6.1  追踪内存消费 668
15.6.2  追踪CPU的使用 668
15.6.3  覆盖测试 668
15.6.4  JVM剖析接口 668
15.6.5  使用HPROF 669
15.6.6  线程性能 670
15.6.7  优化指南 671
15.7  doclet 671
15.8  总结 672
15.9  练习 673
第16章  分析与设计 675
16.1  方法学 675
16.2  阶段0:制定计划 676
16.3  阶段1:做什么 677
16.4  阶段2:如何构建 679
16.4.1  对象设计的五个阶段 680
16.4.2  对象开发指南 681
16.5  阶段3:构建系统核心 681
16.6  阶段4:迭代用例 681
16.7  阶段5:演化 682
16.8  成功的计划 683
16.9  极限编程 683
16.9.1  优先编写测试 683
16.9.2  结对编程 684
16.10  过渡策略 685
16.10.1  指南 685
16.10.2  管理上的障碍 686
16.11  总结 687
附录A  对象的传递与返回 689
附录B  Java编程指南 723
附录C  补充材料 731
附录D  资源 735
索引 739

教学资源推荐
作者: 顾元刚 等
作者: [美]奥弗·曼德勒维奇(Ofer Mendelevitch) 凯西·斯特拉(Casey Stella) 著 道格拉斯·伊德理恩(Douglas Eadline)
作者: (美)Harvey M.Deitel,Paul J.Deitel
作者: George Coulouris, Jean Dollimore, Tim Kindberg
参考读物推荐
作者: 段艺 涂伟忠 编著
作者: (美)Bill Blunden
作者: Kevin Mukhar Chris Zelenak James L.Weaver Jim Crume