# 1.11 Java和因特網
既然Java不過另一種類型的程序設計語言,大家可能會奇怪它為什么值得如此重視,為什么還有這么多的人認為它是計算機程序設計的一個里程碑呢?如果您來自一個傳統的程序設計背景,那么答案在剛開始的時候并不是很明顯。Java除了可解決傳統的程序設計問題以外,還能解決World Wide Web(萬維網)上的編程問題。
## 1.11.1 什么是Web?
Web這個詞剛開始顯得有些泛泛,似乎“沖浪”、“網上存在”以及“主頁”等等都和它拉上了一些關系。甚至還有一種“Internet綜合癥”的說法,對許多人狂熱的上網行為提出了質疑。我們在這里有必要作一些深入的探討,但在這之前,必須理解客戶端/服務器系統的概念,這是充斥著許多令人迷惑的問題的又一個計算領域。
**1. 客戶端/服務器計算**
客戶端/服務器系統的基本思想是我們能在一個統一的地方集中存放信息資源。一般將數據集中保存在某個數據庫中,根據其他人或者機器的請求將信息投遞給對方。客戶端/服務器概述的一個關鍵在于信息是“集中存放”的。所以我們能方便地更改信息,然后將修改過的信息發放給信息的消費者。將各種元素集中到一起,信息倉庫、用于投遞信息的軟件以及信息及軟件所在的那臺機器,它們聯合起來便叫作“服務器”(Server)。而對那些駐留在遠程機器上的軟件,它們需要與服務器通信,取回信息,進行適當的處理,然后在遠程機器上顯示出來,這些就叫作“客戶”(Client)。
這樣看來,客戶端/服務器的基本概念并不復雜。這里要注意的一個主要問題是單個服務器需要同時向多個客戶提供服務。在這一機制中,通常少不了一套數據庫管理系統,使設計人員能將數據布局封裝到表格中,以獲得最優的使用。除此以外,系統經常允許客戶將新信息插入一個服務器。這意味著必須確保客戶的新數據不會與其他客戶的新數據沖突,或者說需要保證那些數據在加入數據庫的時候不會丟失(用數據庫的術語來說,這叫作“事務處理”)。客戶軟件發生了改變之后,它們必須在客戶端器上構建、調試以及安裝。所有這些會使問題變得比我們一般想象的復雜得多。另外,對多種類型的計算機和操作系統的支持也是一個大問題。最后,性能的問題顯得尤為重要:可能會有數百個客戶同時向服務器發出請求。所以任何微小的延誤都是不能忽視的。為盡可能緩解潛伏的問題,程序員需要謹慎地分散任務的處理負擔。一般可以考慮讓客戶端負擔部分處理任務,但有時亦可分派給服務器所在地的其他機器,那些機器亦叫作“中間件”(中間件也用于改進對系統的維護)。
所以在具體實現的時候,其他人發布信息這樣一個簡單的概念可能變得異常復雜。有時甚至會使人產生完全無從著手的感覺。客戶端/服務器的概念在這時就可以大顯身手了。事實上,大約有一半的程序設計活動都可以采用客戶端/服務器的結構。這種系統可負責從處理訂單及信用卡交易,一直到發布各類數據的方方面面的任務——股票市場、科學研究、政府運作等等。在過去,我們一般為單獨的問題采取單獨的解決方案;每次都要設計一套新方案。這些方案無論創建還是使用都比較困難,用戶每次都要學習和適應新界面。客戶端/服務器問題需要從根本上加以變革!
**2. Web是一個巨大的服務器**
Web實際就是一套規模巨大的客戶端/服務器系統。但它的情況要復雜一些,因為所有服務器和客戶都同時存在于單個網絡上面。但我們沒必要了解更進一步的細節,因為唯一要關心的就是一次建立同一個服務器的連接,并同它打交道(即使可能要在全世界的范圍內搜索正確的服務器)。
最開始的時候,這是一個簡單的單向操作過程。我們向一個服務器發出請求,它向我們回傳一個文件,由于本機的瀏覽器軟件(亦即“客戶”或“客戶程序”)負責解釋和格式化,并在我們面前的屏幕上正確地顯示出來。但人們不久就不滿足于只從一個服務器傳遞網頁。他們希望獲得完全的客戶端/服務器能力,使客戶(程序)也能反饋一些信息到服務器。比如希望對服務器上的數據庫進行檢索,向服務器添加新信息,或者下一份訂單等等(這也提供了比以前的系統更高的安全要求)。在Web的發展過程中,我們可以很清晰地看出這些令人心喜的變化。
Web瀏覽器的發展終于邁出了重要的一步:某個信息可在任何類型的計算機上顯示出來,毋需任何改動。然而,瀏覽器仍然顯得很原始,在用戶迅速增多的要求面前顯得有些力不從心。它們的交互能力不夠強,而且對服務器和因特網都造成了一定程度的干擾。這是由于每次采取一些要求編程的操作時,必須將信息反饋回服務器,在服務器那一端進行處理。所以完全可能需要等待數秒乃至數分鐘的時間才會發現自己剛才拼錯了一個單詞。由于瀏覽器只是一個純粹的查看程序,所以連最簡單的計算任務都不能進行(當然在另一方面,它也顯得非常安全,因為不能在本機上面執行任何程序,避開了程序錯誤或者病毒的騷擾)。
為解決這個問題,人們采取了許多不同的方法。最開始的時候,人們對圖形標準進行了改進,使瀏覽器能顯示更好的動畫和視頻。為解決剩下的問題,唯一的辦法就是在客戶端(瀏覽器)內運行程序。這就叫作“客戶端編程”,它是對傳統的“服務器端編程”的一個非常重要的拓展。
## 1.11.2 客戶端編程(注釋⑧)
Web最初采用的“服務器-瀏覽器”方案可提供交互式內容,但這種交互能力完全由服務器提供,為服務器和因特網帶來了不小的負擔。服務器一般為客戶瀏覽器產生靜態網頁,由后者簡單地解釋并顯示出來。基本HTML語言提供了簡單的數據收集機制:文字輸入框、復選框、單選鈕、列表以及下拉列表等,另外還有一個按鈕,只能由程序規定重新設置表單中的數據,以便回傳給服務器。用戶提交的信息通過所有Web服務器均能支持的“通用網關接口”(CGI)回傳到服務器。包含在提交數據中的文字指示CGI該如何操作。最常見的行動是運行位于服務器的一個程序。那個程序一般保存在一個名為“cgi-bin”的目錄中(按下Web頁內的一個按鈕時,請注意一下瀏覽器頂部的地址窗,經常都能發現“cgi-bin”的字樣)。大多數語言都可用來編制這些程序,但其中最常見的是Perl。這是由于Perl是專為文字的處理及解釋而設計的,所以能在任何服務器上安裝和使用,無論采用的處理器或操作系統是什么。
⑧:本節內容改編自某位作者的一篇文章。那篇文章最早出現在位于`www.mainspring.com`的Mainspring上。本節的采用已征得了對方的同意。
今天的許多Web站點都嚴格地建立在CGI的基礎上,事實上幾乎所有事情都可用CGI做到。唯一的問題就是響應時間。CGI程序的響應取決于需要傳送多少數據,以及服務器和因特網兩方面的負擔有多重(而且CGI程序的啟動比較慢)。Web的早期設計者并未預料到當初綽綽有余的帶寬很快就變得不夠用,這正是大量應用充斥網上造成的結果。例如,此時任何形式的動態圖形顯示都幾乎不能連貫地顯示,因為此時必須創建一個GIF文件,再將圖形的每種變化從服務器傳遞給客戶。而且大家應該對輸入表單上的數據校驗有著深刻的體會。原來的方法是我們按下網頁上的提交按鈕(Submit);數據回傳給服務器;服務器啟動一個CGI程序,檢查用戶輸入是否有錯;格式化一個HTML頁,通知可能遇到的錯誤,并將這個頁回傳給我們;隨后必須回到原先那個表單頁,再輸入一遍。這種方法不僅速度非常慢,也顯得非常繁瑣。
解決的辦法就是客戶端的程序設計。運行Web瀏覽器的大多數機器都擁有足夠強的能力,可進行其他大量工作。與此同時,原始的靜態HTML方法仍然可以采用,它會一直等到服務器送回下一個頁。客戶端編程意味著Web瀏覽器可獲得更充分的利用,并可有效改善Web服務器的交互(互動)能力。
對客戶端編程的討論與常規編程問題的討論并沒有太大的區別。采用的參數肯定是相同的,只是運行的平臺不同:Web瀏覽器就象一個有限的操作系統。無論如何,我們仍然需要編程,仍然會在客戶端編程中遇到大量問題,同時也有很多解決的方案。在本節剩下的部分里,我們將對這些問題進行一番概括,并介紹在客戶端編程中采取的對策。
**1. 插件**
朝客戶端編程邁進的時候,最重要的一個問題就是插件的設計。利用插件,程序員可以方便地為瀏覽器添加新功能,用戶只需下載一些代碼,把它們“插入”瀏覽器的適當位置即可。這些代碼的作用是告訴瀏覽器“從現在開始,你可以進行這些新活動了”(僅需下載這些插入一次)。有些快速和功能強大的行為是通過插件添加到瀏覽器的。但插件的編寫并不是一件簡單的任務。在我們構建一個特定的站點時,可能并不希望涉及這方面的工作。對客戶端程序設計來說,插件的價值在于它允許專業程序員設計出一種新的語言,并將那種語言添加到瀏覽器,同時不必經過瀏覽器原創者的許可。由此可以看出,插件實際是瀏覽器的一個“后門”,允許創建新的客戶端程序設計語言(盡管并非所有語言都是作為插件實現的)。
**2. 腳本編制語言**
插件造成了腳本編制語言的爆炸性增長。通過這種腳本語言,可將用于自己客戶端程序的源碼直接插入HTML頁,而對那種語言進行解釋的插件會在HTML頁顯示的時候自動激活。腳本語言一般都傾向于盡量簡化,易于理解。而且由于它們是從屬于HTML頁的一些簡單正文,所以只需向服務器發出對那個頁的一次請求,即可非常快地載入。缺點是我們的代碼全部暴露在人們面前。另一方面,由于通常不用腳本編制語言做過份復雜的事情,所以這個問題暫且可以放在一邊。
腳本語言真正面向的是特定類型問題的解決,其中主要涉及如何創建更豐富、更具有互動能力的圖形用戶界面(GUI)。然而,腳本語言也許能解決客戶端編程中80%的問題。你碰到的問題可能完全就在那80%里面。而且由于腳本編制語言的宗旨是盡可能地簡化與快速,所以在考慮其他更復雜的方案之前(如Java及ActiveX),首先應想一下腳本語言是否可行。
目前討論得最多的腳本編制語言包括JavaScript(它與Java沒有任何關系;之所以叫那個名字,完全是一種市場策略)、VBScript(同Visual Basic很相似)以及Tcl/Tk(來源于流行的跨平臺GUI構造語言)。當然還有其他許多語言,也有許多正在開發中。
JavaScript也許是目常用的,它得到的支持也最全面。無論NetscapeNavigator,Microsoft Internet Explorer,還是Opera,目前都提供了對JavaScript的支持。除此以外,市面上講述JavaScript的書籍也要比講述其他語言的書多得多。有些工具還能利用JavaScript自動產生網頁。當然,如果你已經有Visual Basic或者Tcl/Tk的深厚功底,當然用它們要簡單得多,起碼可以避免學習新語言的煩惱(解決Web方面的問題就已經夠讓人頭痛了)。
**3. Java**
如果說一種腳本編制語言能解決80%的客戶端程序設計問題,那么剩下的20%又該怎么辦呢?它們屬于一些高難度的問題嗎?目前最流行的方案就是Java。它不僅是一種功能強大、高度安全、可以跨平臺使用以及國際通用的程序設計語言,也是一種具有旺盛生命力的語言。對Java的擴展是不斷進行的,提供的語言特性和庫能夠很好地解決傳統語言不能解決的問題,比如多線程操作、數據庫訪問、連網程序設計以及分布式計算等等。Java通過“程序片”(Applet)巧妙地解決了客戶端編程的問題。
程序片(或“小應用程序”)是一種非常小的程序,只能在Web瀏覽器中運行。作為Web頁的一部分,程序片代碼會自動下載回來(這和網頁中的圖片差不多)。激活程序片后,它會執行一個程序。程序片的一個優點體現在:通過程序片,一旦用戶需要客戶軟件,軟件就可從服務器自動下載回來。它們能自動取得客戶軟件的最新版本,不會出錯,也沒有重新安裝的麻煩。由于Java的設計原理,程序員只需要創建程序的一個版本,那個程序能在幾乎所有計算機以及安裝了Java解釋器的瀏覽器中運行。由于Java是一種全功能的編程語言,所以在向服務器發出一個請求之前,我們能先在客戶端做完盡可能多的工作。例如,再也不必通過因特網傳送一個請求表單,再由服務器確定其中是否存在一個拼寫或者其他參數錯誤。大多數數據校驗工作均可在客戶端完成,沒有必要坐在計算機前面焦急地等待服務器的響應。這樣一來,不僅速度和響應的靈敏度得到了極大的提高,對網絡和服務器造成的負擔也可以明顯減輕,這對保障因特網的暢通是至關重要的。
與腳本程序相比,Java程序片的另一個優點是它采用編譯好的形式,所以客戶端看不到源碼。當然在另一方面,反編譯Java程序片也并不是件難事,而且代碼的隱藏一般并不是個重要的問題。大家要注意另外兩個重要的問題。正如本書以前會講到的那樣,編譯好的Java程序片可能包含了許多模塊,所以要多次“命中”(訪問)服務器以便下載(在Java 1.1中,這個問題得到了有效的改善——利用Java壓縮檔,即JAR文件——它允許設計者將所有必要的模塊都封裝到一起,供用戶統一下載)。在另一方面,腳本程序是作為Web頁正文的一部分集成到Web頁內的。這種程序一般都非常小,可有效減少對服務器的點擊數。另一個因素是學習方面的問題。不管你平時聽別人怎么說,Java都不是一種十分容易便可學會的語言。如果你以前是一名Visual Basic程序員,那么轉向VBScript會是一種最快捷的方案。由于VBScript可以解決大多數典型的客戶端/服務器問題,所以一旦上手,就很難下定決心再去學習Java。如果對腳本編制語言比較熟,那么在轉向Java之前,建議先熟悉一下JavaScript或者VBScript,因為它們可能已經能夠滿足你的需要,不必經歷學習Java的艱苦過程。
**4. ActiveX**
在某種程度上,Java的一個有力競爭對手應該是微軟的ActiveX,盡管它采用的是完全不同的一套實現機制。ActiveX最早是一種純Windows的方案。經過一家獨立的專業協會的努力,ActiveX現在已具備了跨平臺使用的能力。實際上,ActiveX的意思是“假如你的程序同它的工作環境正常連接,它就能進入Web頁,并在支持ActiveX的瀏覽器中運行”(IE固化了對ActiveX的支持,而Netscape需要一個插件)。所以,ActiveX并沒有限制我們使用一種特定的語言。比如,假設我們已經是一名有經驗的Windows程序員,能熟練地使用象C++、Visual Basic或者BorlandDelphi那樣的語言,就能幾乎不加任何學習地創建出ActiveX組件。事實上,ActiveX是在我們的Web頁中使用“歷史遺留”代碼的最佳途徑。
**5. 安全**
自動下載和通過因特網運行程序聽起來就象是一個病毒制造者的夢想。在客戶端的編程中,ActiveX帶來了最讓人頭痛的安全問題。點擊一個Web站點的時候,可能會隨同HTML網頁傳回任何數量的東西:GIF文件、腳本代碼、編譯好的Java代碼以及ActiveX組件。有些是無害的;GIF文件不會對我們造成任何危害,而腳本編制語言通常在自己可做的事情上有著很大的限制。Java也設計成在一個安全“沙箱”里在它的程序片中運行,這樣可防止操作位于沙箱以外的磁盤或者內存區域。
ActiveX是所有這些里面最讓人擔心的。用ActiveX編寫程序就象編制Windows應用程序——可以做自己想做的任何事情。下載回一個ActiveX組件后,它完全可能對我們磁盤上的文件造成破壞。當然,對那些下載回來并不限于在Web瀏覽器內部運行的程序,它們同樣也可能破壞我們的系統。從BBS下載回來的病毒一直是個大問題,但因特網的速度使得這個問題變得更加復雜。
目前解決的辦法是“數字簽名”,代碼會得到權威機構的驗證,顯示出它的作者是誰。這一機制的基礎是認為病毒之所以會傳播,是由于它的編制者匿名的緣故。所以假如去掉了匿名的因素,所有設計者都不得不為它們的行為負責。這似乎是一個很好的主意,因為它使程序顯得更加正規。但我對它能消除惡意因素持懷疑態度,因為假如一個程序便含有Bug,那么同樣會造成問題。
Java通過“沙箱”來防止這些問題的發生。Java解釋器內嵌于我們本地的Web瀏覽器中,在程序片裝載時會檢查所有有嫌疑的指令。特別地,程序片根本沒有權力將文件寫進磁盤,或者刪除文件(這是病毒最喜歡做的事情之一)。我們通常認為程序片是安全的。而且由于安全對于營建一套可靠的客戶端/服務器系統至關重要,所以會給病毒留下漏洞的所有錯誤都能很快得到修復(瀏覽器軟件實際需要強行遵守這些安全規則;而有些瀏覽器則允許我們選擇不同的安全級別,防止對系統不同程度的訪問)。
大家或許會懷疑這種限制是否會妨礙我們將文件寫到本地磁盤。比如,我們有時需要構建一個本地數據庫,或將數據保存下來,以便日后離線使用。最早的版本似乎每個人都能在線做任何敏感的事情,但這很快就變得非常不現實(盡管低價“互聯網工具”有一天可能會滿足大多數用戶的需要)。解決的方案是“簽了名的程序片”,它用公共密鑰加密算法驗證程序片確實來自它所聲稱的地方。當然在通過驗證后,簽了名的一個程序片仍然可以開始清除你的磁盤。但從理論上說,既然現在能夠找到創建人“算帳”,他們一般不會干這種蠢事。Java 1.1為數字簽名提供了一個框架,在必要時,可讓一個程序片“走”到沙箱的外面來。
數字簽名遺漏了一個重要的問題,那就是人們在因特網上移動的速度。如下載回一個錯誤百出的程序,而它很不幸地真的干了某些蠢事,需要多久的時間才能發覺這一點呢?這也許是幾天,也可能幾周之后。發現了之后,又如何追蹤當初肇事的程序呢(以及它當時的責任有多大)?
**6. 因特網和內聯網**
Web是解決客戶端/服務器問題的一種常用方案,所以最好能用相同的技術解決此類問題的一些“子集”,特別是公司內部的傳統客戶端/服務器問題。對于傳統的客戶端/服務器模式,我們面臨的問題是擁有多種不同類型的客戶計算機,而且很難安裝新的客戶軟件。但通過Web瀏覽器和客戶端編程,這兩類問題都可得到很好的解決。若一個信息網絡局限于一家特定的公司,那么在將Web技術應用于它之后,即可稱其為“內聯網”(Intranet),以示與國際性的“因特網”(Internet)有別。內聯網提供了比因特網更大的安全級別,因為可以物理性地控制對公司內部服務器的使用。說到培訓,一般只要人們理解了瀏覽器的常規概念,就可以非常輕松地掌握網頁和程序片之間的差異,所以學習新型系統的開銷會大幅度減少。
安全問題將我們引入客戶端編程領域一個似乎是自動形成的分支。若程序是在因特網上運行,由于無從知曉它會在什么平臺上運行,所以編程時要特別留意,防范可能出現的編程錯誤。需作一些跨平臺處理,以及適當的安全防范,比如采用某種腳本語言或者Java。
但假如在內聯網中運行,面臨的一些制約因素就會發生變化。全部機器均為Intel/Windows平臺是件很平常的事情。在內聯網中,需要對自己代碼的質量負責。而且一旦發現錯誤,就可以馬上改正。除此以外,可能已經有了一些“歷史遺留”的代碼,并用較傳統的客戶端/服務器方式使用那些代碼。但在進行升級時,每次都要物理性地安裝一道客戶程序。浪費在升級安裝上的時間是轉移到瀏覽器的一項重要原因。使用了瀏覽器后,升級就變得易如反掌,而且整個過程是透明和自動進行的。如果真的是牽涉到這樣的一個內聯網中,最明智的方法是采用ActiveX,而非試圖采用一種新的語言來改寫程序代碼。
面臨客戶端編程問題令人困惑的一系列解決方案時,最好的方案是先做一次投資/回報分析。請總結出問題的全部制約因素,以及什么才是最快的方案。由于客戶端程序設計仍然要編程,所以無論如何都該針對自己的特定情況采取最好的開發途徑。這是準備面對程序開發中一些不可避免的問題時,我們可以作出的最佳姿態。
## 1.11.3 服務器端編程
我們的整個討論都忽略了服務器端編程的問題。如果向服務器發出一個請求,會發生什么事情?大多數時候的請求都是很簡單的一個“把這個文件發給我”。瀏覽器隨后會按適當的形式解釋這個文件:作為HTML頁、一幅圖、一個Java程序片、一個腳本程序等等。向服務器發出的較復雜的請求通常涉及到對一個數據庫進行操作(事務處理)。其中最常見的就是發出一個數據庫檢索命令,得到結果后,服務器會把它格式化成HTML頁,并作為結果傳回來(當然,假如客戶通過Java或者某種腳本語言具有了更高的智能,那么原始數據就能在客戶端發送和格式化;這樣做速度可以更快,也能減輕服務器的負擔)。另外,有時需要在數據庫中注冊自己的名字(比如加入一個組時),或者向服務器發出一份訂單,這就涉及到對那個數據庫的修改。這類服務器請求必須通過服務器端的一些代碼進行,我們稱其為“服務器端的編程”。在傳統意義上,服務器端編程是用Perl和CGI腳本進行的,但更復雜的系統已經出現。其中包括基于Java的Web服務器,它允許我們用Java進行所有服務器端編程,寫出的程序就叫作“小服務程序”(Servlet)。
## 1.11.4 一個獨立的領域:應用程序
與Java有關的大多數爭論都是與程序片有關的。Java實際是一種常規用途的程序設計語言,可解決任何類型的問題,至少理論上如此。而且正如前面指出的,可以用更有效的方式來解決大多數客戶端/服務器問題。如果將視線從程序片身上轉開(同時放寬一些限制,比如禁止寫盤等),就進入了常規用途的應用程序的廣闊領域。這種應用程序可獨立運行,毋需瀏覽器,就象普通的執行程序那樣。在這兒,Java的特色并不僅僅反應在它的移植能力,也反映在編程本身上。就象貫穿全書都會講到的那樣,Java提供了許多有用的特性,使我們能在較短的時間里創建出比用從前的程序設計語言更健壯的程序。
但要注意任何東西都不是十全十美的,我們為此也要付出一些代價。其中最明顯的是執行速度放慢了(盡管可對此進行多方面的調整)。和任何語言一樣,Java本身也存在一些限制,使得它不十分適合解決某些特殊的編程問題。但不管怎樣,Java都是一種正在快速發展的語言。隨著每個新版本的發布,它變得越來越可愛,能充分解決的問題也變得越來越多。
- Java 編程思想
- 寫在前面的話
- 引言
- 第1章 對象入門
- 1.1 抽象的進步
- 1.2 對象的接口
- 1.3 實現方案的隱藏
- 1.4 方案的重復使用
- 1.5 繼承:重新使用接口
- 1.6 多態對象的互換使用
- 1.7 對象的創建和存在時間
- 1.8 異常控制:解決錯誤
- 1.9 多線程
- 1.10 永久性
- 1.11 Java和因特網
- 1.12 分析和設計
- 1.13 Java還是C++
- 第2章 一切都是對象
- 2.1 用引用操縱對象
- 2.2 所有對象都必須創建
- 2.3 絕對不要清除對象
- 2.4 新建數據類型:類
- 2.5 方法、參數和返回值
- 2.6 構建Java程序
- 2.7 我們的第一個Java程序
- 2.8 注釋和嵌入文檔
- 2.9 編碼樣式
- 2.10 總結
- 2.11 練習
- 第3章 控制程序流程
- 3.1 使用Java運算符
- 3.2 執行控制
- 3.3 總結
- 3.4 練習
- 第4章 初始化和清除
- 4.1 用構造器自動初始化
- 4.2 方法重載
- 4.3 清除:收尾和垃圾收集
- 4.4 成員初始化
- 4.5 數組初始化
- 4.6 總結
- 4.7 練習
- 第5章 隱藏實現過程
- 5.1 包:庫單元
- 5.2 Java訪問指示符
- 5.3 接口與實現
- 5.4 類訪問
- 5.5 總結
- 5.6 練習
- 第6章 類復用
- 6.1 組合的語法
- 6.2 繼承的語法
- 6.3 組合與繼承的結合
- 6.4 到底選擇組合還是繼承
- 6.5 protected
- 6.6 累積開發
- 6.7 向上轉換
- 6.8 final關鍵字
- 6.9 初始化和類裝載
- 6.10 總結
- 6.11 練習
- 第7章 多態性
- 7.1 向上轉換
- 7.2 深入理解
- 7.3 覆蓋與重載
- 7.4 抽象類和方法
- 7.5 接口
- 7.6 內部類
- 7.7 構造器和多態性
- 7.8 通過繼承進行設計
- 7.9 總結
- 7.10 練習
- 第8章 對象的容納
- 8.1 數組
- 8.2 集合
- 8.3 枚舉器(迭代器)
- 8.4 集合的類型
- 8.5 排序
- 8.6 通用集合庫
- 8.7 新集合
- 8.8 總結
- 8.9 練習
- 第9章 異常差錯控制
- 9.1 基本異常
- 9.2 異常的捕獲
- 9.3 標準Java異常
- 9.4 創建自己的異常
- 9.5 異常的限制
- 9.6 用finally清除
- 9.7 構造器
- 9.8 異常匹配
- 9.9 總結
- 9.10 練習
- 第10章 Java IO系統
- 10.1 輸入和輸出
- 10.2 增添屬性和有用的接口
- 10.3 本身的缺陷:RandomAccessFile
- 10.4 File類
- 10.5 IO流的典型應用
- 10.6 StreamTokenizer
- 10.7 Java 1.1的IO流
- 10.8 壓縮
- 10.9 對象序列化
- 10.10 總結
- 10.11 練習
- 第11章 運行期類型識別
- 11.1 對RTTI的需要
- 11.2 RTTI語法
- 11.3 反射:運行期類信息
- 11.4 總結
- 11.5 練習
- 第12章 傳遞和返回對象
- 12.1 傳遞引用
- 12.2 制作本地副本
- 12.3 克隆的控制
- 12.4 只讀類
- 12.5 總結
- 12.6 練習
- 第13章 創建窗口和程序片
- 13.1 為何要用AWT?
- 13.2 基本程序片
- 13.3 制作按鈕
- 13.4 捕獲事件
- 13.5 文本字段
- 13.6 文本區域
- 13.7 標簽
- 13.8 復選框
- 13.9 單選鈕
- 13.10 下拉列表
- 13.11 列表框
- 13.12 布局的控制
- 13.13 action的替代品
- 13.14 程序片的局限
- 13.15 視窗化應用
- 13.16 新型AWT
- 13.17 Java 1.1用戶接口API
- 13.18 可視編程和Beans
- 13.19 Swing入門
- 13.20 總結
- 13.21 練習
- 第14章 多線程
- 14.1 反應靈敏的用戶界面
- 14.2 共享有限的資源
- 14.3 堵塞
- 14.4 優先級
- 14.5 回顧runnable
- 14.6 總結
- 14.7 練習
- 第15章 網絡編程
- 15.1 機器的標識
- 15.2 套接字
- 15.3 服務多個客戶
- 15.4 數據報
- 15.5 一個Web應用
- 15.6 Java與CGI的溝通
- 15.7 用JDBC連接數據庫
- 15.8 遠程方法
- 15.9 總結
- 15.10 練習
- 第16章 設計模式
- 16.1 模式的概念
- 16.2 觀察器模式
- 16.3 模擬垃圾回收站
- 16.4 改進設計
- 16.5 抽象的應用
- 16.6 多重分發
- 16.7 訪問器模式
- 16.8 RTTI真的有害嗎
- 16.9 總結
- 16.10 練習
- 第17章 項目
- 17.1 文字處理
- 17.2 方法查找工具
- 17.3 復雜性理論
- 17.4 總結
- 17.5 練習
- 附錄A 使用非JAVA代碼
- 附錄B 對比C++和Java
- 附錄C Java編程規則
- 附錄D 性能
- 附錄E 關于垃圾收集的一些話
- 附錄F 推薦讀物