前言
歡迎閱讀本書。Java是一種很容易學會的成熟的編程語言,同時,它也匯集各種技術于一身,經常令初學者不知道從何入手。如果你也有同感,那么本書就很適合你,因為這是一本特意為初學者量身定制的教程。
作為面向初學者的教程,本書不是要教會你每一種Java技術(因為薄薄一本書是不可能囊括所有Java技術的,這也是大部分Java類書籍都只專注于某一種技術的原因)。應該說,本書涵蓋了最重要的Java編程技術,使你能以此為基礎進而學習其他技術。本書的內容依然豐富,只要你真正理解所有章節的內容,并且完成練習,你將完全能夠勝任一名中級Java程序員的日常工作。
本書共三大主題,這些是一名專業級Java程序員必須熟練掌握的內容:
Java編程語言;
Java面向對象編程(OOP);
Java核心類庫。
要想把以上三大主題組織好一本高效的Java教材之所以困難,正是因為以下兩方面的原因。一方面,Java是一種面向對象編程(OOP)的語言,如果你已經了解OOP的話,就會知道它的語法是比較容易學的。另一方面,OOP特性(如繼承、多態以及數據封裝),用現實的案例進行示范也很容易。問題在于,理解真實的Java程序需要具備Java核心類庫的知識。
由于它們之間的相輔相成關系,這三大主題并沒有劃分成三個獨立的部分,而是討論某一主題的章節會與討論另一主題的章節相互交織在一起。例如,在解釋多態之前,我要先確保你了解某些Java類,之后才能講解真實的案例。此外,如泛型這樣的語言特性,如果你事先不理解某些類,是無法解釋清楚的,因此我就會在講完那些基礎類之后再討論泛型。
還有這樣的情況:某一個主題可能會在兩個甚至更多個地方出現。例如,for語句是一項基本的語言特性,它應該在較前面的章節中進行討論。但是,for還可以用來迭代一組對象,這種特性則又只能在講完“集合框架”之后再做討論。因此,for最早在第3章中出現,之后在第11章中再度出現。
接下來,我要在此首先高度概述一下Java,粗略介紹一下面向對象編程(OOP)的概念,并簡要地描述每一章的主要內容,以及講述如何安裝Java軟件。
Java語言和技術
Java不僅是一種面向對象的編輯語言,它還是使軟件開發變得更加快速并且獲得更健壯、更安全的應用程序的一系列技術。多年來,Java之所以會成為首選的編程技術,是因為它具有如下優勢。
平臺獨立性
易用性
加速應用程序開發的完整類庫
安全性
可擴展性
廣泛的行業支持
Sun Microsystems公司于1995年開發出Java,隨后Java(盡管它從一開始就是一種通用的語言)成為編寫Applet(在Web瀏覽器上運行的小程序,為靜態的網站增添交互性)的著名語言。互聯網的快速發展有很大一部分要歸功于Java早期的成功。
然而,Applet并不是令Java魅力四射的唯一因素。Java最吸引人的另一個特性是它的平臺獨立性承諾,也就是“一次編寫,到處運行”(Write Once, Run Anywhere)的口號。這意味著編寫一個程序就可以在Windows、UNIX、Mac、Linux及其他操作系統上運行。這是任何其他編程語言都無法實現的。當時,C和C++是開發常規應用程序時最常用的兩種語言。Java自誕生之日起,似乎就搶盡了它們的風頭。
這就是Java 1.0。
1997年,Java 1.1發布了,它增加了一些更加重要的特性,例如,更好的事件模型、Java Beans以及國際化(internationalization,i18n)。
1998年12月,Java 1.2發布了。在它發布3天之后,版本號由1變成了2,它標志著于1999年開始掀起的一場以Java作為“下一代”技術的銷售戰役拉開了序幕。Java 2以4種風格出售:標準版(J2SE)、企業版(J2EE),移動版(J2ME),以及Java Card版本(從未在這個品牌名稱中采用“2”)。
接下來于2000年發布了1.3版,也就是J2SE 1.3。兩年之后發布1.4版,即J2SE 1.4。J2SE 1.5于2004年發布。但是Java 2 的1.5版隨后改成了Java 5。
2006年11月13日,即Java 6正式發布前的一個月,Sun Microsystems公司宣布Java變成開源了。Java SE 6是Sun Microsystems公司誠邀外部開發者貢獻代碼和幫助修復bug后的第一個Java版本。其實,Sun公司過去也曾接受過非本公司員工的參與,如Doug Lea在多線程方面的付出,但這是Sun公司第一次發出公開的邀請。Sun公司承認他們的資源有限,在不久的將來,外界的參與者將會幫助他們畫上完美的句號。
2007年5月,Sun公司把其Java源代碼作為免費軟件在OpenJDK社區發布。IBM、Oracle和Apple公司隨后也都紛紛加入了OpenJDK。
2010年,Oracle公司收購了Sun公司。
Java 7(代號Dolphin)于2011年7月發布,這也是通過OpenJDK進行開源合作的成果。
是什么使Java平臺能夠獨立
你一定聽說過“平臺獨立”或者“跨平臺”這類術語,它意味著程序可以在多種操作系統上運行。這也是使Java深得人心的一大原因。但是,到底是什么使Java得以實現平臺獨立呢?
在傳統的編程中,源代碼是要編譯成可執行代碼的。這種可執行代碼只能在所設計的平臺上運行。換句話說,為Windows而編寫和編譯的代碼就只能在Windows上運行,在Linux中編寫的代碼就只能在Linux上運行,等等。
傳統的編程范例
而Java程序則編譯成字節碼(bytecode)。你不能讓它自己運行字節碼,因為它不是本機代碼(native code)。字節碼只能在Java虛擬機(JVM)上運行。JVM是一種解釋字節碼的本機應用程序。Sun公司使JVM在眾多平臺上都可用,從而把Java變成一種跨平臺的語言。如圖I.2所示,同一個字節碼就可以在任何操作系統的JVM上運行。
Java編程模式
目前,JVM適用于Windows、UNIX、Linux、Free BSD,以及世界上在用的其他的所有主流操作系統。
JDK、JRE、JVM之間有何區別
我說過,Java程序必須進行編譯。事實上,任何編程語言都需要一個編譯器,經過編譯后編程語言才真正有用。編譯器是一種將程序源代碼轉化成可執行格式(如字節碼、本機代碼或者其他)的程序。在開始利用Java編程之前,必須先下載一個Java編譯器。Java編譯器是一個名為javac的程序,它是Java compiler的縮寫。
雖然javac可以將Java源代碼編譯成字節碼,但要運行字節碼,還需要一個Java虛擬機(JVM)。此外,由于你常常需要用到Java核心類庫中的類,因此還需要下載這些類庫。Java運行時環境(Java Runtime Environment,JRE)包含JVM和類庫。當然,Windows的JRE與Linux的JRE不同,也就是說,某一種操作系統的JRE與另一種操作系統的JRE是不同的。
Java軟件有兩個發行包:
JRE,它包括JVM和核心類庫,最適合用來運行字節碼。
JDK,它包括JRE,外加一個編譯器和其他工具。它是編寫和編譯Java程序的必備軟件。
簡而言之,JVM就是一種運行字節碼的本機應用程序。JRE則是一種包含JVM和Java類庫的環境。JDK則包含JRE及一個Java編譯器和其他工具。
JDK的第一個版本是1.0,之后的版本依次是1.1、1.2、1.3、1.4、1.5、1.6和1.7。對于微小的更新發布,則是在版本號之后再添加一個數字。例如,1.7.1就是對1.7版本的第一次微小的更新。
JDK 1.7(代號Dolphin)就是大家熟知的JDK 7。JDK所包含的JRE版本與JDK的相同。因此,JDK 1.7包含JRE 1.7。JDK經常也稱做SDK(Software Development Kit的縮寫)。
除了JDK之外,Java程序員還需要下載說明核心類庫中類的Java文檔。從提供JRE和JDK的同一個網址可以下載說明文檔。
Java 2、J2SE、J2EE、J2ME、Java 7究竟為何物
Sun公司為推廣Java做了很多努力。它的部分營銷策略是冠以Java 2的名稱,實際上就是JDK 1.2。Java 2有三種版本:
Java 2 Platform,標準版(J2SE)。J2SE其實相當于JDK。它也是J2EE中所定義的各種技術的基礎。
Java 2 Platform,企業版(J2EE)。它為開發基于組件的多層企業應用程序定義了標準。功能包括Web Services特性支持和開發工具(SDK)。
Java 2 Platform,移動版(J2ME)。它為在消費者設備上運行的應用程序提供了一種環境,如移動電話、掌上電腦(PDA),以及電視機頂盒等。J2ME包括一個JVM和有限的幾組類庫。
在版本5中出現了名稱的變化。J2SE變成了Java Platform,Standard Edition 5(Java SE 5)。而且J2EE和J2ME中的“2”也去掉了。企業版的當前版本是Java Platform,Enterprise Edition 6(Java EE 6)。J2ME現在稱做Java Platform,Micro Edition(Java ME,沒有版本號)。在本書中,Java 7就是指Java SE 7。
與Sun公司出產的第一個Java版本不同,Java SE 7(包括J2SE 1.4、Java SE 5以及Java SE 6)是一系列規范,這些規范定義了在發布時需要實現的各種特性。軟件本身稱做參考實現(Reference Implementation)。Oracle、IBM和其他公司一起,通過OpenJDK提供了Java SE 7參考實現,以及Java后續版本的參考實現。
Java EE 6也屬于規范,其中包含像Servlet、JavaServer Pages、JavaServer Faces、Java Messaging Service等技術。為了開發和運行J2EE和Java EE 6應用程序,還需要一個J2EE/Java EE 6應用服務器(application server)。任何人都可以實現一個J2EE/Java EE 6應用服務器。這說明市場上各種應用服務器很容易獲取到,其中包括一些開源的應用服務器。下面列舉了一些J2EE/Java EE 6應用服務器的例子:
Oracle公司的WebLogic(之前BEA的WebLogic)
IBM公司的WebSphere
Sun公司的Sun Java Application Server
Oracle公司的10g Application Server
GlassFish
JBoss
Jonas
Apache Geronimo
JBoss、GlassFish、Jonas以及Geronimo都是開源的應用服務器。不過它們有不同的許可要求,因此在決定使用這些產品之前,一定要確保先讀過許可內容。
Java社區進程程序
Java之所以能夠持續成為技術首選,有很大一部分要歸功于Sun公司的策略,它允許其他行業的人士參與決定Java的未來。這使得很多人都覺得Java也屬于他們每一個人。許多大公司(如IBM、Oracle、Nokia、Fujitsu等)都大力投資Java,因為它們也可以為某一種技術提出一種規范,并將它們想要的技術放到Java技術的下一個版本中。這種協同工作正是采用了Java社區進程(Java Community Process,JCP)程序的形式。它的網址是http://www.jcp.org。
由JCP程序提出的規范,就是大家所熟悉的Java Specification Requests(JSR)。例如JSR 336定義了Java SE 7。
面向對象編程概述
面向對象編程(Object-Oriented Programming,OOP)是根據真實的對象來構建應用程序模型而實現的。OOP的三個原則是封裝、繼承和多態。
OOP的好處是實實在在的。這些正是大多數現代編程語言(包括Java),均是面向對象(OO)的原因所在。我甚至可以列舉為了支持OOP而做出的兩個著名的語言轉變:C語言演變成C++,Visual Basic更新成Visual Basic.NET。
本節將闡明OOP的優勢,并評估學習OOP的難易程度。
OOP的優勢
OOP的優勢包括代碼易維護、可重用,以及易擴展。下面就詳細地介紹這些優勢。
1. 易維護。現代的軟件應用規模往往都十分巨大。以前,“大”系統包括幾千行代碼。現在,即使有上百萬行代碼也算不上大。C++之父Bjarne Stroustrup曾經說過,當一個系統變得越來越大時,就會開始給它的開發者帶來很多問題。一個小程序可以用任何語言以任何方式編寫。如果你不輕易放棄,最終還是可以使它運行起來。但大型的程序就是另一回事了。如果沒有采用“好的編程”方法,一邊修復錯誤的同時會不斷出現新的錯誤。
其原因在于,大型程序的不同部分之間是相互依賴的。當在程序的某個部分中修改某些東西時,可能不知道這個變化會對程序的其他部分造成什么樣的影響。OOP則可以很容易地使程序模塊化,這種模塊性大大減少了維護的問題。在OOP中,模塊性是可以繼承的,因為類(對象的一個模板)本身就是一個模塊。好的設計應該允許類包含類似的功能性和有關的數據。OOP中經常用到的一個重要的相關術語是耦合,它表示兩個模塊之間的交互程度。不同部分之間的松耦合會使代碼更容易實現重用,這就是OOP的另一個好處。
2. 可重用。可重用意味著之前寫好的代碼可以被代碼的創建者或需要該源代碼所提供功能的其他人重用。那么,OOP語言經常提供一些預先設計好的類庫也就不足為奇了。在Java中,它配套提供了幾百個類庫或API(應用編程接口),這些都是經過精心設計和測試過的。編寫和發布自己的類庫時也非常容易。支持編程平臺中的可重用性,這是十分吸引人的,因為它可以大大縮短開發時間。
類可重用性的一大困難是,要為類庫創建好的文檔。作為一名程序員,他要找到一個能夠為其提供所需功能的類能有多快?是找一個這樣的類快呢,還是從頭寫一個新的類更快?值得慶幸的是,Java核心和擴展的API都提供了詳實的文檔。
可重用性不僅適用于重用類和其他類型的編碼階段;在OO系統中設計應用程序時,針對OO設計問題的解決方案也可以重用。這些解決方案稱做設計模式。為了便于引用各解決方案,每種模式都有一個名字。可重用設計模式的早期說明請見經典著作《Design Patterns:Elements of Reusable Object-Oriented Software》,由Erich Gamma、Richard Helm、Ralph Johnson和John Vlissides合著。
3. 可擴展性。每一個應用程序都是獨特的。它有自己的需求和規范。說到可重用性,有時候你可能找不到現成的類來為你提供應用程序所需的精確功能。但是,你或許可以找到一兩個能夠提供部分功能的類。可擴展性的意思是,你仍然可以使用那些類,方法是對它們進行擴展,使其滿足你的需要。這樣做你依然節省了時間,因為不必從頭編寫代碼。
在OOP中,可擴展性是通過繼承來實現的。可以擴展現成的類,對它添加一些方法或者數據,或者修改不喜歡方法的行為。如果你知道某個基本功能將多次使用,但又不想讓類提供太具體的功能,就可以提供一個泛型類,以后可以對它進行擴展,使它能夠提供特定于某個應用程序的功能。
學習OOP很困難嗎
Java程序員必須掌握OOP。事實上,如果你使用過程語言(如C或者Pascal)編過程序,就會發現它們之間有很大的區別。這其中有好有壞。
先說壞的方面。
研究人員一直在探討在學校里傳授OOP的最佳方法;有人認為,最好在教OOP之前先教過程編程。我們看到有許多地方,都是在學生臨近大學畢業時才上OOP課程。
但是現在有越來越多的學生認為,具備過程編程能力的人,在模式中的思維,與OO程序員看待和解決問題的方式有很大的不同。當需要學習OOP時,他所面臨的最大困難是要克服模式轉換。據說,要經過6~18個月才能將一個人的思維從過程模式轉換成面向對象的模式。另有研究表明,沒有學過過程編程的學生則不覺得OOP有多么難學。
接下來說好的方面。
Java堪稱最容易學習的OOP語言之一。例如,你不需要操心指針,不必浪費寶貴的時間去解決因沒有銷毀不用的對象而導致的內存泄漏等。此外,在它們早期的版本中,還提供了非常全面的類庫,并且bug相對要少得多。一旦掌握了OOP,用Java編程就變得非常容易了。
關于本書
下面概述一下各章節的主要內容:
第1章旨在讓讀者體驗使用Java的感覺。其中包括編寫一個簡單的Java程序,利用javac工具對它進行編譯,并利用java程序運行它。此外,還提出了一些關于編碼規范和集成開發環境的建議。
第2章講解Java語言的語法。該章將介紹字符集、基本類型、變量、運算符等話題。
第3章講解Java語句for、while、do-while、if、if-else、switch、break和continue。
第4章是本書中第一節關于OOP的課程。該章首先說明什么是Java對象,以及它在內存中是如何保存的。隨后繼續講解類、類成員,以及兩個OOP概念(抽象和封裝)。另外還簡單地介紹了一些有關的主題,如垃圾回收和對象比較。
第5章涵蓋Java核心類庫中重要的那些類:java.lang.Object、java.lang.String、java.lang.StringBuffer和java.lang.StringBuilder、包裝類,以及java.util.Scanner。這里面還介紹了裝箱/拆箱和可變參數。這是十分重要的一章,因為其中介紹的類是Java中最常用的一部分類。
第6章介紹一種能夠使代碼具有可擴展性的OOP特性。該章教你如何擴展類,改變子類的可見性,覆蓋方法等。
毫無疑問,錯誤處理是所有編程語言的一項重要特性。作為一種成熟的語言,Java具備十分強健的錯誤處理機制,它可以有效地防止bug蔓延。第7章詳細介紹這一機制。
第8章講解在使用數字和日期時要處理的三個問題:解析、格式化和操作。該章介紹可以幫助你完成這些任務的Java類。
第9章說明接口不僅僅是一個沒有實現的類,它還定義服務提供者和客戶端之間的契約。本章講解如何使用接口和抽象類。
第10章主要講解枚舉,這是從Java 5開始添加的一個類型。
第11章說明如何利用java.util包中的成員,將對象進行分組,并對它們進行操作。
泛型是Java中非常重要的一項特性,第12章詳細解釋這一特性。
第13章介紹流的概念,并闡述如何利用java.io包中的4個流類型來執行輸入/輸出操作。此外,還講解對象序列化和反序列化。
第14章講解如何在一個類的內部編寫另一個類,并說明為什么這項OOP特性非常有用。
第15章是本書中關于Swing的兩章之一,這是第一章。它簡單地介紹AWT組件,并詳細介紹一些基礎的Swing組件。
第16章是關于Swing的第二章。它介紹一些更高級的技術,如布局管理、事件處理,以及Swing的外觀。
多態是OOP的重要利器之一。當我們在編譯中不知道對象的類型時,多態的作用尤其出乎我們的想象。第17章講解這一特性,并給出很好的范例。
第18章討論Java中的一項特性。它介紹JDK中配套的標準注解、一般注解、元注解,以及定制注解。
如今,軟件應用程序可以部署到不同的國家和地區,這是很平常的事。這些應用程序切記要設計成國際化。第19章探討Java程序員可以使用的方法。
Applet是指可以在Web瀏覽器上運行的小程序。第20章講解Applet的生命周期、安全性限制,以及JApplet。
第21章介紹了網絡編程中使用的類。這里用一個簡單的Web服務器應用程序來說明如何使用這些類。
訪問數據庫和操作數據是業務應用程序中最重要的部分任務。數據庫服務器種類繁多,訪問不同的數據庫需要不同的技能。值得Java程序員感到慶幸的是,JDBC(Java Database Connectivity)技術為訪問數據庫提供了統一的方法。JDBC將在第22章討論。
線程是指操作系統分配處理器時間的一個基本處理單元,在一個進程里面可以有不止一個線程在執行代碼。第23章說明在Java中多線程編程并不是只有專家級程序員才能做到。
第24章是本書中關于多線程編程的第二章。這里介紹了能使多線程編程變得更加容易的接口和類。
第25章講解Java應用程序的用戶可以如何限制運行Java應用程序,以及可以如何利用加密術來保護應用程序和數據的安全。
第26章探討Servlet技術和Servlet API,并舉了幾個例子。
第27章介紹另一種Web開發技術,并講解如何編寫JSP頁面。
第28章介紹javadoc工具,Java程序員可以用它為API產生文檔。
第29章介紹Java Web Start,以及如何用它將Java應用程序部署到互聯網、局域網,甚至如何從CD進行部署。
附錄A、附錄B和附錄C分別介紹javac、java和jar工具。
附錄D和附錄E分別簡要地講解NetBeans和Eclipse開發工具。