前言
关于第三版
Java 8是Java社区的新伙伴。 Java 7是对以前版本的重大改进。自本书上一版出版以来, Java已发生了太多的变化! Java 5中出现的新功能如注解、泛型类型、并发机制等已普遍存在了。在Java的整个画面中, API来了又走: JavaME已经过时很久了,BlackBerry已经放弃了它;在部分企业级Java中, JSF正在(慢慢)替代JSP; Spring框架继续扩大其覆盖面。许多人似乎认为桌面Java已经死亡,甚至整个Java正在逐步灭亡,但它肯定还没离开舞台;Swing、 JavaFX、 Java企业版以及 (尽管Oracle有重大诉讼案件) Android正在使Java语言保持活力。此外,在其他“ JVM语言”方面出现了更新的关注,如Groovy、 JRuby、 Jython、 Scala和Clojure正在使Java平台处于世界的开发前沿。
实际上,第三版的主要挑战在于缩短对流行的API的介绍,保持自己应有的特色并尽量避免有偏见,使本书符合由O’Reilly手册系列和之前版本所确定的厚度约束。因此,本书不得不保留900多页,这当然不是我努力适应“所有亮点”的结果。
我还去掉了前一版本中的一些API介绍。最明显的是在介绍串口和并口的一章(在第10章中将有关内容消减为一节);电脑一般不使用这些了,几乎也没有人使用它们了:大家的注意力都转移到了USB口,而Java目前似乎还没有一个标准的API(坦率地讲,对此,开发者之间的真正兴趣也不大)。
关于之前版本
如果你了解一点Java的话,那很好。如果你了解更多Java编程的话,那就更好了!如果你了解一些J a v a知识,还想进一步深入学习,那么,本书是你的理想选择。如果你对Java一点都不了解,你应当选择一本更基础的书,如果你是新手,选择 《 Head First Java 》( O’Reilly),如果你是有经验的C程序员,请选择《 Learning Java》( O’Reilly)。
我是1980年在Toronto大学工作时开始使用C语言编程的,在20世纪80年代到90年代期间, C语言为我提供了很好的服务。 1995年,随着新生语言Oak更名为Java,我碰到了好运,我的同事J. Greg Davidson告诉我有关Java的情况。我向Greg提供的地址发送了一封电子邮件,并在1995年3月收到了来自Java发明者James Gosling的回复,邮件内容如下:
| Hi. A friend told me about WebRunner( ?), your extensible network
| browser. It and Oak( ?) its extension language, sounded neat. Can
| you please tell me if it's available for play yet, and/or if any
| papers on it are available for FTP?
Check out http://java.sun.com
( oak got renamed to java and webrunner got renamed to
hotjava to keep the lawyers happy)
因此,在我开始使用之前, Oak已经变成了Java注1。我下载了HotJava,并尝试使用它。开始我并不太相信这个新奇的语言,它看起来像错位的C/C++。我编写了测试和演示程序,并将其放入javasrc目录下,以使它们与我的C源代码相互独立(因为程序经常会重名)。随着我对Java了解得越多,我开始看到它用于许多工作中的优势,比如,自动内存回收(“垃圾回收”)以及指针运算符的去除。 javasrc目录下的文件在持续增加。我编写了一本Java教程“ Learning Tree” 注2,目录下的文件增长得更快了,为此,我不得不创建子目录,尽管如此,查找东西还是越来越困难,显然,对文档的需求就变得迫切了。
在某种意义上,本书是源自我的javasrc目录和为另一种新语言所建立的文档框架的高速碰撞的结果。在O’Reilly公司出版的《 Perl Cookbook》一书中, Tom Christiansen和Nathan Torkington通过他们成功的设计,将当时较新的Perl语言材料以一个个称为“实例”的精短的文章展示给大家。这样一本书最初的模型当然来自人们熟悉的厨房食谱。将“ cookbook”术语用于列举与计算机相关的操作技巧已有很长的历史。
在软件方面, Donald Knuth用 “ cookbook”来比喻他的书《 The Art of Computer Programming》( Addison-Wesley),该书于1968年首印。在硬件方面, Don Lancaster 编写了《 The TTL Cookbook》一书 ( Sams)。( Transistor-transistor logic, TTL,是当时电子电路的小规模构建块)。 Tom 和 Nathan在这方面做得很成功,我想向希望学习更多Perl语言的人们推荐这本书。实际上,本书正是为那些想深入学习Java的人们而编写的。
每节中的代码都是高度独立的,在你的项目中可随意使用其中的代码。代码的发布符合Berkeley风格的版权,以打击成批的盗版行为。
读者对象
我假定你有一些Java基础。在本书中不会告诉你怎样使用println同时输出一个字符串和一个数字,或怎样编写一个对JFrame扩展的类并将你的名字输出到窗口中。我假设你已经学习过Java课程或看过一本入门类的书籍,如《 Head First Java》、《LearningJava》或《 Java in a Nutshell 》( O’Reilly)。然而,第1章介绍了一些你可能了解不深的技术,掌握它们对理解后面的内容是非常必要的。请尽管跳着阅读本书!书的打印版和电子版都有大量的相互交叉引用。
本书内容
与我的Perl同事Tom 和Nathan不同,我不需要在语言的古怪和习语方面花费太多时间。 Java是一种简洁明了的语言,没有太多的怪异之处注3。但这并不是说学好Java是件轻松的事!如果是的话,本书的出版将没有必要了。我的主要精力是集中在Java API上。我将通过例子教你了解重要的API是什么,它们擅长用于哪些方面。
像P e r l一样, J a v a也是一种伴随你成长的语言。我承认我目前大部分时间都在使用Java。以前用C语言编写的程序除了其中用于设备驱动和遗留系统的之外,我现在都用Java实现了。
不过, Java比Perl更适合不同范围的任务。 Perl(和其他脚本语言,如awk和Python)尤其适用“ one-liner”(一句话)式的应用任务。正如Tom和Nathan所说, Perl擅长像从文件中打印第42行这样的事情。 Java当然也能实现,但它似乎更适合“大型应用的开发”或企业应用的开发,因为它是可编译的面向对象的语言。实际上,在Java 2中添加的大部分API都是为了实现这种类型的开发。不过,我将以较短的例子甚至是代码片段来对这些技术进行必要的说明。我会确保你看到的每个代码片段都能编译并运行。
本书中较长的例子是我最初编写的一些将日常工作自动化的工具,例如, MkIndex工具(见javasrc库)可在我的Java例子源代码所在位置读取顶层目录,并为这个顶层目录构建一个浏览器能打开的index.html文件。另一个例子就是本书第一版的主体部分可用XML标记(见20章)。我使用XML格式输入本书部分章节的内容,并给这些初始文本加上标记,然后就可用XmlForm程序将文本转换为出版软件要求的格式。这个程序还能完成从javasrc目录插入书的手稿的全部和部分代码。 XmlForm的讨论见20章。
本书内容结构
让我们看看本书的内容结构。第1章入门:编译、运行和调试Java程序,描述了在不同平台上编译程序、在不同环境中运行(浏览器、命令行、窗口桌面)和调试的一些方法。
第2章与运行环境交互,从编译转向运行程序,以使其适应周围的环境,周围环境是指在你的电脑中运行的其他程序。接下来的几章处理基本的API。
第3章字符串,主要阐述Java中基本但很强大的数据类型,显示了怎样合并、分离、比较和重新排列文本。
第4章正则表达式的模式匹配,教你如何使用UNIX的强大的正则表达式实现字符串匹配和模式匹配。“ Regex”处理成为Java标准已有多年历史了,但如果你不知道怎么使用它,你可以“重塑轮胎”。
第5章数字,同时介绍了内置的数字类型如int和double,以及对应的API类( Integer,Double等)及其类型转换。还简单提了“大数”类。由于Java程序员经常以本地化和国际化形式处理日期和时间,第6章日期和时间——新的API,涵盖了这一重要话题。
接下来的两章介绍了数据处理部分。与大多数语言中的一样, Java中的数组是由相似类型的对象构成的线性的索引集合,见第7章结构化数据。本章还继续介绍了许多集合类的使用,这是一种存储大量java.util包中对象的强有力的方式,包括使用“ Java泛型”。
尽管Java在语法上与过程式语言,如C有些相似,但Java核心是面向对象的编程语言( OOP)。第8章面向对象技术,讨论了一些适用于Java的OOP的关键概念,包括常见的java.lang.Object的覆盖方法和设计模式这一重要问题。
Java不是而且永远也不会是纯“函数编程”( FP)语言。不过,它可能使用FP的一些观点,而且在Java 8及其对lambda表达式(又名“闭包”)的支持下会越来越多地使用。参见第9章函数编程技术:函数接口、流、并行集合。
接下来的几章介绍传统的输入和输出。第10章输入输出,讲读取和写入文件的规则(如果你觉得文件比较繁琐,请不要跳过这一章,因为这是后面两章的基础。你需要在本章介绍的串口或并口,以及在第13章网络客户端中讲的一个基于套接字的网络连接上读/写数据)。第11章目录和文件系统运算符,展示了文件以外的任何操作,例如识别它们的大小以及最后更新时间,还介绍了如何读取和修改目录、如何创建临时文件,以及重命名磁盘上的文件。
第12章媒体:图形、视频、音频,将我们带进GUI的开发中。这一章内容是底层细节(如绘制图形及设置字体和颜色)和非常高级的活动(如控制视频剪辑或电影)的混合。第14章图形用户接口中,介绍了GUI的高级话题,如按钮、标签、菜单等类似的GUI预定义组件的使用。一旦有了GUI程序(实际上,在你真正写它之前),你会想读第15章国际化和本地化的内容,这样在阿克巴、阿富汗、阿尔及尔、阿姆斯特丹和英格兰运行你的程序将和在阿尔伯塔、阿肯色州、阿拉巴马州等地运行结果一样。
因为Java一开始就被标榜为“ Internet上的编程语言”,所以应该在本书中花费一些时间讨论J a v a的网络编程。第13章网络客户端,涵盖了客户端网络编程的基础,主要集中在套接字技术上。在本书第三版第13章网络客户端中已重新从Applet和Web客户端转向强调Web服务的客户端。今天,有许多应用程序需要访问Web服务,主要是RESTful服务,而这似乎是必要的。然后我们将转向服务器端,见第16章Java服务器端,在这一章中,你将学到一些服务器端的编程技术。
网络编程常常需要生成或处理电子邮件,第17章对此话题做了介绍。
第18章数据库访问,涵盖了高级数据库访问( JPA和Hibernate)和低级Java数据库连接( JDBC)的要点,展示了怎样连接本地或远程关系数据库、怎样存储和检索数据,以及怎样找到查询结果集或数据库中的信息。
用于数据交换的一个简单的基于文本的表示是JSON,即JavaScript Object Notation( JavaScript对象符号)。第19章处理JSON数据,描述了格式以及处理格式的一些API。
另一种用于存储和交换数据的文本形式是XML。第20章处理XML,讨论了XML格式及在用SAX和DOM这两种标准Java API进行解析时使用的运算符。
第21章包和打包,展示了怎样创建一起使用的类的包。本章还讨论了怎样发布或分发并安装你的软件。
第22章Java线程,告诉你怎样编写一次执行多个任务的类,并利用强大的多线程硬件的优势。
第23章反射或命名类的类,向你揭示如何编写API的交叉参考文档(在你的有生之年成为Java书籍的作者!),以及Web服务器怎样能装载任意旧的Servlet(以前从未看到过特定的类)并运行它。
有时你已经有现成的代码,该代码使用另一种语言编写,且能为你实现一部分工作,或者你想用Java作为一个更大包的一部分。第24章Java和其他语言的结合,展示了怎样运行外部程序(已编译或脚本程序)以及怎样直接与C/C++或其他语言编写的本地码交互。
我不可能在一本八百多页的书中讲述Java的全部内容,后记中是一些结语和指向我的在线Java API总结的链接,每个Java开发者都应该了解这些内容。
最后,附录A按照发布时间线给出了Java颇具故事性的历史,不论你学过Java的哪一版本,你都可以跳到这里,很快赶上。
没有两个程序员或作者能在展示所有Java话题的最佳顺序上达成一致。为帮助你更好地学习,我在书中建立了额外的交叉引用,大多数引用的是章节号。
平台说明
Java经历了许多版本的变迁,见附录A。本书主要针对Java 7和Java 8平台。在本书出版前,我期望所有开发中的Java项目都使用Java 6或Java 7,只有几个地方由于历史原因与早期版本有关(注意Java 6在本版出版前约一年时间已处于“生命尽头”状态)。
我已在几种操作系统组合下和多个Java版本下对javasrc归档中的代码进行了编译,以测试这一代码的可移植性。
Java API由两部分组成:核心API和非核心API。根据定义,核心API包含在JDK中,你可以免费从Java网站( http://java.com/)下载。非核心API是其余部分。但即使是这个核心部分,却一点也不小,它将近50个包, 3000多个公有类,平均每个类有12个左右的方法。只调用核心API的程序可以在任何标准Java平台上运行。
Java非核心API进一步可分为标准扩展部分和非标准扩展部分。所有标准扩展API的包名都以javax开始。但请注意,并不是所有以javax命名的包都是扩展API: javax.swing及其子包Swing GUI包以前是扩展API,但现在是核心API的一部分。实现每个标准扩展API并不需要Java的许可(如Apple或IBM公司),但如果需要,就应坚持使用标准扩展的接口。本书中依赖于标准扩展API的代码都会引起你的注意,除了在书中所列举的代码外,几乎很少的代码是依赖于非标准扩展的。我自己的包com.darwinsys包含一些在这里或那里用得着的实用类,在使用这个包中的类时,你会看到在文件顶部有一条导入语句。
此外,另两个平台Java ME 和Java EE也是标准定义的平台。 Java微版( Java ME)用于小型设备如手持设备、移动电话、传真机等。在Java ME内,有针对不同设备类的各种“描述”。相对的, Java企业版( Java EE)则用于构建大型可扩展的分布式应用。
Servlets、 JavaServer Pages、 JavaServer Faces、 CORBA、 RMI、 JavaMail、 Enterprise JavaBeans ( EJBs)、 Transactions以及其他的API都是Java EE的一部分。 Java ME 和Java EE包名通常以“ javax”开始,因为它们不是核心包。本书中没有讨论这些内容,
但包含了几个EE API可用于客户端程序,如JavaMail。如前所述,第一版中的Servlets和JSP在本版中已移除,因为现在有《 Java Servlet and JSP Cookbook》( http://shop.oreilly.com/product/9780596005726.do)一书专门讨论它们。
谈到手机和移动设备,你可能知道A n d r o i d系统使用了J a v a作为其编程语言。对J a v a开发者而言,值得欣慰的是, A n d r o i d系统也使用了大多数核心J a v a A P I,而Swing和AWT除外,因为Android系统对此提供了Android特定的替代品。那些想学习Android的Java开发者可以参阅《 Android Cookbook》( http://shop.oreilly.com/product/0636920010241.do)一书或该书的网站。