Java 2 1. 習題參考解答 2006/01/02

advertisement
Java 2 程式設計範例教本
習題參考解答 2006/01/02
第 1 章:程式語言與 Java 的基礎
1.
「程式」(Programs)是使用指定程式語言所撰寫沒有混淆文字、
數值和鍵盤符號所組成的特殊符號,這些符號組合成指令和敘述,再進
一步編寫成程式碼,程式碼可以告訴電腦解決指定問題的步驟。
程式如同一個轉換器,當從電腦鍵盤或滑鼠取得輸入資料後,執行程式
就可以將資料轉換成有用的資訊。換句話說,為了讓電腦能夠看懂程
式,程式需要依據程式語言的規則、結構和語法,以指定的文字或符號
來撰寫程式,例如:Java 程式語言撰寫的程式稱為 Java 程式碼(Java
Code),或稱為「原始碼」(Source Code)。
「軟體」(Softwares)是一種電腦執行的應用程式,通常軟體是一
個或多個程式的泛稱,或是一整套應用程式的總稱,「應用程式」
(Applications)是一種處理指定工作的電腦程式,例如:數學分析、文
書處理、試算表和程式語言開發工具等。
程式語言的種類
目前電腦的程式語言相當多,程式語言隨著電腦科技的進步,已經
延伸出龐大的族群,在程式語言的分類上,以發展的世代來分,如下表
所示:
世代
程式語言
2
Java 2 程式設計範例教本
第一世代
機器語言(Machine Languages)
第二世代
組合語言(Assembly Languages)
第三世代
高階語言(High Level Languages)
第四世代
應 用 程 式 產 生 的 語 言 ( Application-Generation
Languages)或查詢語言(Query Languages)
第五世代

邏輯導向語言(Logic-Oriented Languages)
低階語言(Low Level Languages):低階語言是一種偏向電腦容易
了解的程式語言,屬於電腦看的懂的程式語言,程式執行效率高,
但是使用者不易學習。

高階語言(High Level Languages):高階語言是一種接近人類語言
的程式語言,可以說是一種半英文(Half-english)語言,因為電腦
不能馬上看的懂,需要進一步使用程式進行翻譯,在轉換成機器語
言後,因為轉換出來的程式碼通常比直接使用機器語言撰寫的冗
長,所以效率較低,但是非常適合使用者學習。
2.
目前常見的高階語言有 Java、C/C++、C#、FORTRAN、COBOL、
Pascal、BASIC 和 Borland Delphi 等,高階語言需要進行翻譯,將程式
碼轉譯成機器語言的執行檔案後,才能在電腦上執行,翻譯的方式分為
兩種,如下所示:

編譯程式(Compilers):Java 和 C/C++等程式語言屬於編譯語言,
編譯程式需要檢查完整個程式檔案的程式碼,在完全沒有錯誤的情
況下,才會翻譯成機器語言的程式檔案,其主要的功能有兩項,如
下所示:
習題解答


檢查程式碼的錯誤。

將程式碼翻譯成機器語言的程式碼檔案。
直譯程式(Interpreters):早期的 BASIC 語言(例如:BASICA、
QuickBasic 等)和目前網頁技術的「腳本」(Scripts)語言,例如:
VBScript 和 JavaScript 都屬於直譯語言,直譯程式是一個指令一個動
作,一列一列的執行程式碼,相對的執行效率較低,適合在系統開
發階段的程式除錯。
3.
Java 是一種高階和物件導向程式語言,類似 C++語言的編譯式語
言,不過並不完全相同,因為它是結合編譯和直譯優點的程式語言。
Java 平台
現在讓我們來看看 Java 程式語言的「平台」(Platform),平台是
一種結合硬體和軟體的執行環境,簡單的說,電腦程式是在平台上執
行,因為 Java 屬於一種與硬體無關和跨平台的程式語言,所以 Java 平
台是一種軟體平台,主要是由 JVM 和 Java API 兩個元件所組成。
Java 程式語言的特點
Java 語言是一種簡單、功能強大和高效能的物件導向程式語言,不
只如此,Java 語言還擁有一些傳統程式語言所沒有的特點,如下所示:

分散式(Distributed):Java 語言最初的發展是一種網路程式語言,
可以支援各種網路通訊協定,能夠建立分散式主從架構的應用程
式,輕鬆存取網路上其它主機的資源。
4
Java 2 程式設計範例教本

多執行緒(Multi-Threading):Java 語言支援多執行緒,在同一程式
能夠建 立多 個執行 的小程 式, 稱為「 輕量行 程」 ( Light Weight
Process),以便執行不同的工作,並且支援同步功能,能夠避免
「死結」(Deadlock)情況的發生。

垃圾收集(Garbage Collection):垃圾收集是指如何處理程式不再
使用的記憶體空間,在 C/C++語言需要自行處理記憶體的配置與釋
放,當程式配置的記憶體不再使用時,程式需要提供程式碼釋放記
憶體歸還給作業系統,如此作業系統才能夠再次配置給其它的應用
程式。

例外處理(Exception Handling):電腦程式不可能沒有「小臭蟲」
(Bugs),一些小錯誤可能只會產生錯誤結果,但是有一些小錯誤
可能導致嚴重的系統當機問題,傳統程式語言並沒有完善的例外處
理,所以常常會出現一些不明的系統錯誤。Java 語言的例外處理可
以讓程式更加「強壯」(Robust),這算程式執行時遇到不尋常的
情況,也不會造成程式「崩潰」(Crashing)或整個系統當機。
JVM 和 Java API 兩個元件
4.
Java 編 譯 程 式 可 以 將 Java 原 始 程 式 碼 編 譯 成 「 位 元 組 碼 」
( Bytecode ) , 這 種 程 式 碼 是 一 種 虛 擬 的 機 器 語 言 , 這 台 電 腦 稱 為
「JVM」(Java Virtual Machine),換句話說,在作業系統需要安裝
JVM 的直譯程式,才能夠直譯和執行位元組碼,如下圖所示:
習題解答
上述圖例的 Java 原始程式碼(副檔名.java)在編譯成位元組碼(副
檔名.class)後,就可以在 Windows、UNIX 或 Machintosh 的 Mac OS 作
業系統上執行,只需作業系統安裝 JVM 直譯程式,同一個位元組碼檔
案,就可以跨平台在不同作業系統上正確的執行。
5.
程式語言的「開發環境」(Development Environment)是一組工具
程式用來建立、編譯和維護程式語言所建立的應用程式。目前高階程式
語言大都擁有「整合開發環境」(Integrated Development Environment、
簡稱 IDE),在同一個應用程式就可以編輯、編譯、執行和除錯特定語
言的應用程式。
對於傳統 MS-DOS 或 UNIX、Linux 系統的使用者,或稱為「終端
機」(Terminals)模式,程式執行環境輸入資料和輸出資料都是「命令
列模式」(Command-line Interface),即文字模式的鍵盤輸入或單純文
字 內 容 的 輸 出 , 在 此 環 境 只 需 安 裝 Sun 的 Java 開 發 工 具 「 Java
Development Kit」(JDK),然後配合 vi、edit 或記事本等程式編輯程
式碼,就可以開發 Java 應用程式。
如果是使用視窗環境,在巿面上有很多套支援 Windows 作業系統
的 Java 整合開發環境,只需配合 JDK 就可以在同一工具軟體編輯、編
譯和除錯 Java 程式,常見的 Java 整合開發環境,如下所示:
6
Java 2 程式設計範例教本

Sun Java Studio Standard:Sun 昇陽公司的 Java 整合開發環境,它是
以 NetBeans 應用程式平台為基礎建立的整合開發環境,其網址為:
http://wwws.sun.com/software/sundev/jde/index.html。

NetBeans IDE:NetBeans 是一個開放原始碼計劃,屬於一個全功能
的 Java 整合開發環境,其網址為:http://www.netbeans.org/。

Borland JBuilder:Borland 公司的 Java 整合開發環境,分成數個版
本,Personal 版可以免費下載,其網址:http://www.borland.com。

Gel:Gexperts 公司的免費整合開發環境,這是由 Gerald Nunn 使用
Delphi 所 開 發 支 援 中 文 使 用 介 面 的 Java/JSP IDE , 其 網 址 為 :
http://www.gexperts.com/index.html。

JCreator:Xinox 軟體公司的 JCreator 整合開發環境,這是 Windows
作業系統使用 C++語言所開發的應用程式,分為 LE(Lite Edition)
和 Pro(Pro Edition)兩種版本,其網址:http://www.jcreator.com。
在命令列建立 Java 應用程式
在安裝 JDK 和設定好執行環境後,就可以在 Windows 作業系統的
「命令提示字元」視窗開發 Java 應用程式,程式開發的步驟,如下所
示:
Step 1: 使用記事本或編輯工具建立 Java 原始程式碼檔案,副檔名
為.java。
Step 2: 使用檔名 javac.exe 的 Java 編譯程式,將原始程式檔案編譯成
Bytecode 的類別檔案,副檔名為.class。
習題解答
Step 3: 使用 JVM 直譯程式 java.exe 執行類別檔案,也就是 Java 程
式。
Gel 整合開發工具建立 Java 應用程式
在安裝好 Gel 整合開發環境後,Gel 提供多種方式開發 Java 應用程
式:Java 檔案或專案方式,在本書主要是使用 Java 檔案方式,其程式開
發步驟,如下所示:
Step 1:按二下桌面捷徑【Gel】啟動 Gel,新增 Java 原始碼檔案。
Step 2:輸入程式碼,建立和儲存原始程式碼檔案,副檔名為.java。
Step 3:執行「建造」→「編譯檔案」指令編譯 Java 程式。
Step 4:執行「建造」→「執行檔案」指令執行 Java 程式。
6. .java、.class
7. System.out.println(“大家好!生日快樂”);
8. Test.java、
System.out.println(“大家好!”);
System.out.println(“生日快樂”);
9. javac Test.java、Test.class、java Test
10.
使用多個 System.out.println()輸出星號的字串
第 2 章:變數與運算子
8
Java 2 程式設計範例教本
1.
在程式中需要替變數、類別和函數等很多元素命名,程式設計者在
替這些元素命名時,需要遵循程式語言的語法,Java 的命名語法,如下
所示:

名稱是一個合法的「識別字」(Identifier),識別字是使用英文字母
開頭,不限長度的 Unicode 統一字碼字元的字串,包含字母、數字
和底線”_”。例如:一些合法的名稱範例,如下所示:
T, n, size, z100, long_name, helloWord, Test, apple

名稱區分英文字母的大小寫,例如:apple、Apple 和 APPLE 屬於不
同變數。

名稱不能使用 Java 語法的「關鍵字」(Keyword)、保留字的布林
值 true 或 false 和 null,Java 的關鍵字(這些是程式指令)如下表所
示:
abstract
boolean
break
byte
case
catch
char
class
const
continue
default
do
double
else
extends
final
finally
float
for
goto
if
implements
import
instanceof
int
interface
long
native
new
package
private
protected
public
return
short
static
strictfp
super
switch
synchronized
習題解答
this
throw
throws
void
volatile
while
transient
try
名稱在「範圍」(Scope)中必需是唯一的,例如:在程式中可以使

用相同的變數名稱,不過各變數名稱需要在不同的範圍,詳細的範
圍說明,請參閱第 4 章。
2.
變數的目的是儲存程式執行中的一些暫存資料,程式設計者只需記
住變數名稱,而且知道名稱表示一個記憶體位置中的資料,至於這個記
憶體位置到底有哪裡?並不用傷腦筋,因為這是編譯程式的工作。
簡單的說,程式語言的變數是使用有意義的名稱代表數字的記憶體
位址。Java 變數宣告的語法,如下所示:
資料型態 變數名稱;
上述宣告格式使用資料型態開頭,後面跟著變數名稱,這列程式碼
的目的是「配置一個宣告資料型態的變數」。
Java 擁 有 8 種 基 本 資 料 型 態 byte 、 int 、 short 、 long 、 float 、
double、char 和 boolean,詳細的型態說明請參閱第 2-2 節。例如:整數
變數宣告的範例,如下所示:
int score;
上 述 程 式 碼 宣 告 一 個 整 數 變 數 , 資 料 型 態 為 整 數 int , 名 稱 為
score,如果需要同時宣告多個變數,請使用”,”號分隔,如下所示:
int i, j, score;
上述程式碼在同一列宣告 3 個整數變數 i、j 和 score。
3. float、boolean
10
Java 2 程式設計範例教本
4. zero、lastValue、year2006、TWO-DOLLARS、team、I、j
5. Java 的資料型態分為「基本」(Primitive)和「參考」(Reference)
兩種資料型態,如下所示:

基本資料型態:變數有 byte、short、int、long、float、double、char
和 boolean 共 8 種資料型態,在本節主要說明的就是 Java 的基本資
料型態。

參考資料型態:變數值是一個記憶體位置,這個位置值是物件儲存
的位置,關於這種資料型態的詳細說明請參閱第 5 章,
6.
Java 指定敘述的左邊是「運算式」(Expressions),這是由「運算
子」(Operator)和「運算元」(Operand)所組成,Java 擁有完整的算
術、指定、位元和邏輯運算子,一些運算式的範例,如下所示:
A+B–1
A >= B
A > B && A > 1
上 述 運 算 式 變 數 A 、 B 和 數 值 1 都 屬 於 運 算 元 , ”+” 、 ”“、”>=”、”>”和”&&”為運算子,Java 運算子是使用 1 到 3 個字元所組成
的符號。

--:遞減增運算

&&:AND 運算,連結的兩個運算元都為 true,運算式為 true

!=:不等於

>>:右移運算的位元運算子
7.
下列運算式的值,X 表示運算式不正確,如下所示:
習題解答

5 + 7 = 12

(5 * 6)/2 = 15

(-12 + (12 + 8)/2 ) * 4 = -8

-20 + (14 + 6)/2 ) * 3 = X

(30 - 15) / 3 = 5

34 - 14) / (20 - 5 ) = X

( (34 - 14) / (13 + 7 ) ) = 1

( 1/2 + 3.5) * 2.0 = 7.0

(2 - 6) / 2 + 10 = 8
8.
請參考程式範例 Ch2_3_2.java
9.
參閱第 2-1-5 節的程式範例,將 r 依序設為 10, 20, 50
10.
請參考程式範例 Ch2_2_2.java
11.
使用除法和餘數運算子 250/12, 250%12
12. 1500000 * (1.04) 10
第 3 章:流程控制結構
1.
結構化程式設計是一種組織和撰寫程式碼的技術,使用由上而下的
設計方法(Top-down Design)來分析問題,將程式分解成階層架構的
12
Java 2 程式設計範例教本
「模組」(Modules),每個模組是一段擁有獨立功能的程式碼,而且
只有單一的進入點和離開點,各模組間使用 3 種流程控制來整合:循序
結構(Sequential)、選擇結構(Selection)和重複結構(Iteration)。
總結,結構化程式設計的主要觀念有 3 項,如下所示:

由上而下的設計方法,在第 4 章有進一步的說明。

流程控制結構。

模組(Modules)。
在這一章主要說明 Java 支援結構化程式設計中的各種流程控制結
構。
程式語言撰寫的程式碼大部分是一列指令接著一列指令循序的執
行,但是對於複雜的工作,為了達成預期的執行結果,需要使用「流程
控制結構」(Control Structures)。
循序結構
循序結構是程式預設的執行方式,程式是一個程式敘述接著一個敘
述依序的執行,如下圖所示:
習題解答
選擇結構
選擇結構是一種條件控制敘述,這是一個選擇題,可以分為單一選
擇、二選一或多選一 3 種,程式執行的順序是依照第 2 章關係運算式的
條件,來決定執行哪一個程式區塊的程式碼,如下圖所示:
上述圖例的條件控制敘述如同從公司走路回家,因為回家的路不只
一條,當走到十字路口時,可以決定向左、向右或直走,雖然最終都可
14
Java 2 程式設計範例教本
以到家,但是經過的路徑並不相同,也稱為「決策條件敘述」
(Decision Making Statements)。
重複結構
重複結構是一種迴圈控制,它是重複執行一個程式區塊的程式碼,
提供一個結束條件結束迴圈的執行,依據結束條件測試的位置不同分為
兩種,如下所示:

前測式重複結構:測試迴圈結束條件在程式區塊的開頭,需要符合
條件,才能執行迴圈中程式區塊的程式碼,如下圖所示:

後測式重複結構:測試迴圈結束條件在程式區塊的結尾,所以迴圈
的程式區塊至少會執行一次,如下圖所示:
習題解答
迴圈控制敘述有如馬路上的圓環,車子可以一直繞著圓環開,駕駛
可以隨興蹺幾圈或決定是否離開圓環,進入圓環是進入迴圈,離開圓環
就是離開迴圈。
2.
單一 if/else 指令敘述共有
2
種選擇。寫出下列關係與條件運算式
值是 true 或 false,如下所示:
(1) 2 + 3 == 5
true
(2) 36 < 6 * 6
false
(3) 8 + 1 >= 3 * 3
true
(4) 2 + 1 == (3 + 9) / 4
true
(5) 12 <= 2 + 3 * 2
false
(6) 2 * 2 + 5 != (2 + 1) * 3
false
3.
條件敘述程式片斷的輸出結果,如下所示:
(1) int sum = 8 + 1 + 2 + 7;
if ( sum < 20 )
System.out.println("太小");
else
System.out.println("太大");
 太小
(2) int depth = 10 ;
if ( depth >= 10 )
{ System.out.println("危險: ");
16
Java 2 程式設計範例教本
System.out.println("水太深. ");
}
 危險:
水太深.
4.
do/while 和 while 迴圈敘述(在開頭檢查)的差異是在迴圈的結尾檢查
結束條件,因此 do/while 迴圈的程式區塊至少會執行一次。
5.
下列 main()方法的輸出結果,如下所示:
(1)
2
4
8
16
32
64
(2)
2
4
6
8
10
25
6.
請參考習題 5 (2)的程式碼,加大迴圈和修改 if 條件
7.
if ( amount >= 1000 ) return amount * 0.8;
else return amount;
8.
if ( weight <= 5 )
return weight * 50 + 199;
習題解答
else
return (weight – 5) * 30 + 5* 50 + 199;
9.
30 * ( 1+ (1/2)*(num -1))
10.

1+1/2+1/3+1/4~+1/n
n=50
for (n = 1; n <= 50; n++)
{
total += 1.0/(float) n;
}

1*1+2*2+3*3~+n*n
n=35
for (n = 1; n <= 35; n++)
{
total += n*n;
}
11.
for (i = 1; i <= 120; i++ )
{
num = 3 * i;
}
12.
if ( year > birthday )
age = year - birthday;
else
age = year + 2000 - birthday;
第 4 章:程序與函數的類別方法
1.
模組化是一種解決問題的方法,把一件大型的工作切割成無數的小
工作,切割的工作屬於結構化分析的範疇,我們最常使用的是「由上而
18
Java 2 程式設計範例教本
下的設計方法」(Top-down Design),主要是以程序為單位來切割工
作,也就是所謂的「程序式程式設計」(Procedural Design)。
由上而下的設計方法是在面對問題時,先考慮將整個解決問題的方
法分解成數個大「模組」(Modules),然後針對每一個大模組,一一
分割成數個小模組,如此一直細分,最後等這些細分小問題的小模組完
成後,再將它們組合起來,如此一層層的向上爬,完成整個軟體系統或
應用程式的設計。例如:玩拼圖遊戲一定會先將整個拼圖粗分為數個區
域,等每一個區域都拼好後,整張拼圖也就完成了。
由上而下設計方法在處理問題的過程中,應該注意幾個事項,如下
圖所示:

獨立性:每一個分割模組間的關聯性愈少,處理起來就會愈快。所
謂獨立性,是指當處理某一個子問題時,無需考慮到其它子問題。
換句話說,獨立性是要將每一個問題都定義成一件簡單且明確的問
題。

結合問題:小心控制子問題間的結合方法,而且要注意結合這些子
問題的邏輯順序,避免語焉不詳的結果。

子問題間的溝通:雖然獨立性可以減少各問題間的關聯性,但是並
無法避免掉全部的溝通。因此各問題間如何溝通的問題(即函數的
參數傳遞)也是十分重要的考量。
由上而下的設計方法是結構化程式設計一種相當實用的方法,它並
不是一些嚴格的規則,而是讓我們能夠循序漸進的了解問題,進而發展
出解決問題的方法。
習題解答
很明顯!模組化程式設計是將程式切割成一個個的小程式區塊,這些小
程式區塊的模組就是程序(Subroutines 或 Procedures),每一個程序可
以解決一個小問題,等到所有的小問題都解決了,整個軟體系統或應用
程式也就開發完成。
2.
在程式中執行程序稱為「程序呼叫」(Subroutines Call),我們並
不需要了解程序實際的程式碼,事實上,也不想知道其細節,程序如同
一個「黑盒子」(Black Box),只要告訴我們如何使用這個黑盒子的
「使用介面」(Interface)即可,如下圖所示:
Ch4-2.tif
上述圖例可以看出程式碼只知道呼叫程序時需要傳入的參數,然後
從程序取得傳回值,這種擁有傳回值的程序稱為「函數」
(Functions),這是程序和外部溝通的使用介面,一個對外的邊界,實
際的程序內容是隱藏在使用介面之後,其實際內容的程式碼撰寫稱為
「實作」(Implementation)。
3.
「正式參數」(Formal Parameters)或稱為「假的參數」(Dummy
Parameters),這些正式參數是一個識別字,其角色如同變數,需要指
定資料型態,並且可以在程式碼區塊中使用,如果參數不只一個請使用
「,」符號分隔。
20
Java 2 程式設計範例教本
「實際參數」(Actual Parameters)是參數的值,如果是運算式,
其運算結果的值需要和正式參數定義的資料型態相同,方法的每一個正
式參數都需要對應一個同型態的實際參數。
4. Java 方法傳入的參數擁有 2 種不同的參數傳遞方式,如下表所示:
傳遞方式
說明
傳值呼叫(Call by Value)
將變數值傳入方法,在方法需要另外配
置記憶體空間來儲存參數值,因為擁有
不同的記憶體空間,所以並不會更改呼
叫變數的值
傳址呼叫(Call by Reference) 將 變 數 實 際 儲 存 的 記 憶 體 空 間 位 址 傳
入,所以在方法更改參數值,也會同時
變更原呼叫的變數值
5.
Java 的成員變數是一種類別成員,如同方法一般,當成員變數使用
修飾子 static 時,成員變數就是屬於類別本身,所以稱為「類別變數」
(Class Variables)。
Java 的類別變數是當類別第一次建立時,就配置變數所需的記憶體
空間,直到類別不存在為止,類別變數在類別中的所有方法都可以存取
其值,其宣告的位置是在其它方法的外面,語法格式和區域變數並沒有
什 麼 不 同 , 例 如 : 宣 告 全 域 變 數 ( Global Variables ) 的 計 數 器 變 數
count,如下所示:
public class Ch4_4_1
{ static int count = 1;
……………..
}
習題解答
Java 的 變 數 分 為 類 別 的 成 員 變 數 、 「 方 法 參 數 」 ( Method
Parameters)和區域變數,所以「變數範圍」(Scope)將會影響變數值
的存取,Java 的變數範圍,如下所示:

區域變數範圍(Local Variable Scope):在方法內宣告的變數,變數
只能在宣告程式碼後的程式碼使用(不包括在宣告前),在方法外
的程式碼無法存取此變數。

方法參數範圍(Method Parameter Scope):這是傳入方法的參數
列,其範圍是整個方法的程式區塊,在方法外的程式碼無法存取。

成員變數範圍(Member Variable Scope):不論是 static 宣告的類別
變數或沒有宣告 static(物件的實例變數,詳見第 5 章的說明),在
整個類別的程式碼都可以存取此範圍的變數。
筆者將上述變數範圍整理成圖形,如下圖所示:
6.
Java 的類別或實例方法都允許擁有 2 個以上的同名方法,各同名方
法只需傳遞參數個數或資料型態不同即可,這就是物件導向技術「名稱
再用」的「過載」(Overload),
22
Java 2 程式設計範例教本
因為物件導向程式設計的物件是依接收的訊息(Message)來執行
不同方法,換句話說,只需訊息有差異足以讓物件辨識,就算方法名稱
相同,也一樣可以讓類別或物件執行正確的方法。
例如:2 個同名的類別方法 square(),如下所示:
static int square(int no)
static double square(double no)
上述 2 個方法雖然名稱相同,但是參數的資料型態不同,物件足以
使用資料型態判斷出是 2 個不同方法。接著是參數個數不同的例子,如
下所示:
static int getMin(int a, int b)
static int getMin(int a, int b, int c)
上述同名方法的參數個數為 2 和 3,同理,物件足以使用參數個數
來判斷出是 2 個不同方法。
物 件 導 向 技 術 擁 有 3 個 重 要 觀 念 : 物 件 ( Object ) 、 訊 息
(Message)和類別(Class),簡單說明如下所示:

物件:提供資料和方法的封裝。

訊息:物件間的溝通方式,可以建立互動和支援過過載和多型觀
念。
類別:物件的分類,實作類別架構的繼承。

7.
static int getMax(int a, int b)
{ if ( a > b ) return a;
else
return b;
}
static int getMax(int a, int b, int c)
習題解答
{
// 變數宣告
int temp;
if ( a > b ) temp = a;
else
temp = b;
if ( temp > c ) return temp;
else
return c;
}
8.
num = 1;
for ( a = 10; a >= 1; a--) {
for ( b = 1; b <= a; b++ )
if ( a == b) {
for ( c = 1; c <= num; c++)
// 顯示一個星號
}
else
// 顯示一個空白字元
num += 2;
// 換行
}
9.
static void fibonacci(int n) {
int fn;
// F(n)變數
int fn2;
// F(n-2)變數
int fn1;
// F(n-1)變數
int i;
if ( n <= 1 )
// 項數是否小於 1
System.out.println("["+n+"]"); // 顯示費氏數列
else {
fn2 = 0;
// 設定 F(n-2)
fn1 = 1;
// 設定 F(n-1)
System.out.print("[0][1]"); // 顯示前二項
for ( i = 2; i <= n; i++ ) {// 顯示數列的迴圈
fn = fn2 + fn1;
// 計算各一般項
System.out.print("["+fn+"]"); // 顯示數列
fn2 = fn1;
// 重設 F(n-2)
24
Java 2 程式設計範例教本
fn1 = fn;
}
System.out.println();
// 重設 F(n-1)
}
}
10.
<<<<<$>>>>>
11.
static int mod(int a, int b) {
if ( a < b ) return a;
else return mod(a-b, b);
}
12.
static int num(int x) {
if ( x == 1 ) return 1;
else return num(x-1) + 2x -1;
}
13.
「河內塔」(Tower of Hanoi)問題是說明遞迴觀念時,不可錯過
的一個重要範例,這是流傳在 Brahma 廟內的遊戲,廟內的僧侶相信完
成這個遊戲是一件不可能的任務。河內塔問題共有 3 根木樁,如下圖所
示:
習題解答
上述圖例一共有 n 個盤子放置在第 1 根木樁,盤子的尺寸由上而下
依序遞增。河內塔問題是將所有的盤子從木樁 1 搬移到木樁 3,其搬動
規則,如下所示:

每次只能移動一個盤子,而且只能從最上面的盤子搬動。

盤子可以搬到任何一根木樁。

維持盤子的尺寸是由上而下依序的遞增。
n=1
在木樁上只有 1 個盤子,只需從木樁 1 搬到木樁 3 即可。
n=2
在木樁 1 一共有 2 個盤子,如下圖所示:
Step 1:將盤子從木樁 1 搬移到木樁 2,如下圖所示:
26
Java 2 程式設計範例教本
Step 2:將盤子從木樁 1 搬移到木樁 3,如下圖所示:
Step 3:將盤子從木樁 2 搬移到木樁 3,即可解出河內塔問題,如下圖所
示:
n=3
在木樁 1 上一共有 3 個盤子,如下圖所示:
Step 1:將盤子從木樁 1 搬移到木樁 3,如下圖所示:
習題解答
Step 2:將盤子從木樁 1 搬移到木樁 2,如下圖所示:
Step 3:將盤子從木樁 3 搬移到木樁 2,如下圖所示:
Step 4:將盤子從木樁 1 搬移到木樁 3,如下圖所示:
28
Java 2 程式設計範例教本
Step 5:將盤子從木樁 2 搬移到木樁 1,如下圖所示:
Step 6:將盤子從木樁 2 搬移到木樁 3,如下圖所示:
Step 7:將盤子從木樁 1 搬移到木樁 3,即可完成河內塔問題,如下圖所
示:
第 5 章:類別與物件
1.
物件導向程式語言支援 3 種特性,如下所示:
習題解答

封裝(Encapsulation):封裝是將資料和處理資料的程序與函數組合
起來建立物件。在 Java 語言定義物件是使用「類別」(Class),內
含屬性和方法,屬於一種抽象資料型態(Abstract Data Type),換
句話說,就是替程式語言定義新的資料型態。

繼承(Inheritance):繼承是物件的再利用,當定義好一個類別後,
其它類別可以繼承這個類別的資料和方法,並且新增或取代繼承物
件的資料和方法。

多形(Polymorphism):多形屬於物件導向最複雜的特性,類別如
果需要處理各種不同資料型態時,並不需要針對不同資料型態建立
不同的類別,可以直接繼承基礎類別,繼承此類別建立同名方法處
理不同的資料型態,因為方法的名稱相同,只是程式碼不同,所以
也稱為「同名異式」。
物件基礎程式語言
物件基礎程式語言(Object-based Languages)只提供資料抽象化和
物件觀念,例如:VB 6,不過新版 VB.NET 是物件導向程式語言。
UML 的基礎
UML(Unified Modelling Language)中文稱為塑模語言,UML 的
出現是三位 OO 理論大師:Grady Booch、James Rumbaugh 和 Ivar
Jacobson(通稱 3 Amigo)所提倡,三人本來都各自提出物件導向的方
法論和使用專屬的表示符號,換句話說,同樣的問題,使用三人的方法
論所建立的模型會有 3 種不同的表示方法。
30
Java 2 程式設計範例教本
UML 的發展始於 1994 年 10 月 Grady Booch 和 Jim Rumbaugh 同在
Rational 軟體公司時,開始統一 Booch(Grady Booch 提出的方法論)和
OMT(Object Modeling Technique,Jim Rumbaugh 提出的方法論),
UML 草案版本 0.8 版在 1995 年 10 月提出,1995 年底 Ivar Jacobson 也
加入 Rational 公司後,再整合他的 OOSE(Object-Oriented Software
Engineering)方法論,1997 年 1 月 UML 正式產生,目前 UML 已經是
OMG(Object Management Group)組織的標準。
UML 統一三人表示方法的符號,並不是三位提出的方法論,換句
話說,如同繪製電子元件、工程機械圖的標準符號,UML 是程式語言
的標準符號,以便程式分析者和程式設計者擁有溝通的語言。在本書是
使用 UML 的類別圖來表示 Java 語言的類別宣告和架構。
2.
「物件」(Object)是物件導向技術的關鍵,以程式的角度來說,
物件是資料與相關程序和函數結合在一起的組合體,資料是變數,程序
和函數在 Java 語言稱為方法,如下圖所示:
上述圖例的方法是對外的使用介面,變數和方法都包裹在一個黑盒
子(這個黑盒子比第 4 章程序黑盒子包裝的更加完整),其實作的程式
碼都包裹隱藏起來,稱為「封裝」(Encapsulation)。對於程式設計者
習題解答
來說,我們並不用考慮黑盒子內部的程式碼是如何撰寫,只需要知道這
個物件提供什麼介面和如何使用它。
在現實生活中的物件範例隨處可見,例如:車子、電視、書桌和貓
狗等,這些物件擁有 3 種特性,如下所示:

狀態(State):物件所有「屬性」(Attributes)目前的狀態值,屬
性是用來儲存物件的狀態,可以簡單的只是一個布林值變數,也可
能是另一個物件,例如:車子的車型、排氣量、色彩和自排或手排
等屬性。

行為(Behavior):行為是物件可見部分提供的服務,可以作什麼
事,例如:車子可以發動、停車、加速和換擋等。
識別字(Identity):識別字是用來識別不同的物件,每一個物件都擁有
獨一無二的識別字,Java 語言是使用物件參考(Reference)作為物件的
識別字,簡單的說,就是物件實際儲存的記憶體位址,詳細的說明請參
閱第 5-2-1 節。
類別與物件的關係
Java 的類別是用來建立物件,更正確的說是沒有宣告成 static 的部
分,才是屬於物件原型。它是一種使用者自行定義的資料型態。
當我們使用類別原型建立物件,稱此物件屬於類別的「實例」
( Instance ) 或 稱 為 副 本 , 物 件 的 變 數 稱 為 「 實 例 變 數 」 ( Instance
Variables ) , 物 件 的 程 式 或 函 數 稱 為 「 實 例 方 法 」 ( Instance
Methods),同一個類別可以當作範本建立無數個物件實例,每一個物
件都屬於類別的實例,或直接稱為物件,如下圖所示:
32
Java 2 程式設計範例教本
3. new、無效參考、null
4.
Java 類別宣告的成員資料或方法可以使用 private 和 public 兩種修飾
子指定存取方式,其說明如下所示:

private 修飾子:成員資料或成員方法只能在類別本身呼叫或存取。

public 修飾子:成員資料或方法是此類別建立物件對外的使用介面,
可以讓其它類別的程式碼呼叫此物件的實例方法或存取實例變數。
在 Java 類別的成員方法如果宣告成 public,表示這些方法是物件的
使用介面,但是有一些方法,例如:第 5-2-2 節程式範例的 validDate()
方法因為只有類別本身在呼叫,宣告成 private 供類別本身使用即可,這
種方法稱為「工具方法」(Utility Methods)。
5.
建構子是物件的初始方法,在建立物件時會自動呼叫此方法,建構
子擁有一些特點,如下所示:

建構子與類別同名,例如:類別 Date 的建構函數是 Date()。
習題解答

建構子沒有傳回值。

建構子支援方法的「過載」(Overload)。
6.
類別變數和方法是屬於類別,所有的物件都是使用同一份類別變數
和呼叫同一個類別方法。實例變數和方法屬於個別的物件實例,每一個
物件都各自擁有實例變數和方法。
7. this、this、this
8.
將程式 Ch5_2_3.java 的 validDate()方法改為 static
9.
class Box
{
private double width;
private double height;
private double length;
public Box(double width, double height, double length) {
public double volume() { return width * height * length; }
public double area() { return width * height; }
}
10.
class Time
{
private int hour;
private int minute;
private int second;
public void setHour(int hour) { }
public void setMinute(int min) { }
public void setSecond(int sec) { }
public int getHour() { }
public int getMinute() { }
public int getSecond() { }
private boolean validateTime() { }
}
34
Java 2 程式設計範例教本
public void printTime() { }
……
}
11.
在 Ch5_4.java 新增物件變數 birth_time,如下所示:
class Customer
{
private int id;
private char rank;
private Date birthday;
private Time birth_time;
public Customer(int id, char r, int m, int d, int y) {
public void printCustomer() {
}
}
}
12.
class Counter
{
public static int value;
// 建構子
public Counter(int v) { vlaue = v; }
public void increment() { value++; }
public void decrement() { value--; }
public int getCounter() { }
}
13.
class Books
{
public static int numoftitles;
public static double total;
private String code;
private String title;
private String author;
private double price;
// 建構子
public Books(String code, String title, String author, double price) {
public void setCode(String code) { }
}
習題解答
public void setTitle(String title) { }
public void setAuthor(String author) { }
public void setPrice(double price) { }
public String getCode() { }
public String getTitle() { }
public String getAuthor() { }
public double getPrice() { }
public void printBooks() { }
public double average() { }
}
14.
class Cards
{ // 成員資料
private String name;
private int age;
private String email;
private PhoneList phone; // 物件變數
class PhoneList // PhoneList 內層類別
{ private String homephone;
private String cellphone;
private String officephone;
// 建構子: Phone 內層類別
public Phone(String phone1, String phone2, String phone3)
{
}
// 成員方法: 顯示電話資料
public void printPhone() { }
}
// 建構子:Cards 外層類別
public Cards(String name, ….. String home,String cell)
{ }
// 成員方法: 顯示資料
public void printCards() { }
}
15.
class Customer
{
public String name;
public String address;
36
Java 2 程式設計範例教本
public int age;
public Customer(String name, String address, int age) {
public int getAge() { }
public String getName() { }
public String getAddress() { }
}
}
第 6 章:繼承、抽象類別和多形
1.
「繼承」(Inheritance)是物件導向程式設計的重要觀念,繼承是
一個類別含括現存類別的部分或全部的成員資料和成員方法,並且新增
額外的成員資料或方法,或是覆寫或隱藏繼承類別的方法或變數。
當一個類別是繼承自其它類別,我們稱這個類別為繼承類別的
「子類別」(Subclass)或「延伸類別」(Derived Class),繼承的類別
稱為「父類別」(Superclass)或「基礎類別」(Base Class)。例如:
類別 Nissan 是繼承自類別 Car,繼承關係如下圖所示:
上述圖例是 UML 類別圖,使用空心箭頭線標示類別間的繼承關
係。類別 Car 是類別 Nissan 的父類別,反之,類別 Nissan 是類別 Car 的
習題解答
子類別。如果有多個子類別繼承同一個父類別,每一個子類別稱為「兄
弟類別」(Sibling Classes),如下圖所示:
上述圖例的類別 Truck、Car 和 Motocycle 是兄弟類別。當然還可以
再繼承類別 Car,類別 Nissan 也是類別 Vehicle 的子類別,不過並不是
直接繼承的子類別。
多重繼承
2.
若父類別的方法並不符合子類別的需求,我們可以在子類別宣告同
名、同參數列和傳回值的方法來取代父類別的方法,稱為「覆寫」
(Override)。
不過,物件的實例方法並不能取代類別方法(宣告成 static 的方
法),如果父類別擁有類別方法,子類別需要宣告同樣的類別方法來取
代它,稱為「隱藏」(Hide),覆寫和隱藏的差異,如下表所示:
38
Java 2 程式設計範例教本
父類別的實例方法
父類別的類別方法
子類別的實例方法
覆寫
編譯錯誤
子類別的類別方法
編譯錯誤
隱藏
3.
Java 類別宣告成 final 表示類別不能被繼承,方法宣告成 final 就表示
方法不可以覆寫,至於為什麼使用 final 修飾子?其理由如下所示:

保密原因:基於保密理由,可以將一些類別宣告成 final,以防止子
類別的繼承,存取或覆寫原類別的操作。

設計原因:基於物件導向設計的需求,可以將某些類別宣告成
final,以避免子類別的繼承。
Java 的類別宣告成 abstract 表示是一個抽象類別,抽象類別不能用
來建立物件,只能繼承抽象類別宣告子類別。在抽象類別同時可以使用
abstract 宣告方法為抽象方法,表示方法只有原型宣告,實作的程式碼是
在子類別建立,而且繼承的子類別一定要實作這些抽象方法。
final、abstract
4.
習題解答
Computer 類別可以作為抽象類別
5.
請參閱第 6-3 節。
6. (1)
類別乙、丙和丁
(2) 類別乙和丁
(3) 類別丁
7. MidTerm 的類別宣告,如下所示:
class Test
{ public int num;
public String name;
public Test(int num, String name) {
}
public void printTest() {
}
}
class MidTerm extends Test
{ private int numOfStudents;
public MidTerm(int no, String name, int numOfStudents)
{
super(no, name);
this.numOfStudents = numOfStudents;
}
public void printMidTerm()
{ super.printTest();
System.out.println(super.name);
}
}
8.
呼叫 greeting()方法實際的物件,如下所示:
(1) Card crd = new BirthDay("江小魚", 36);
crd.greeting(); ---------------BirthDay
(2) Card crd = new Vaentine(“小龍女”, 16);
crd.greeting(); ---------------Vaentine
(3) Card crd = new Holiday(“陳會安”);
crd.greeting(); ---------------Holiday
40
Java 2 程式設計範例教本
9.
完成的 Java 程式碼,如下所示:
Card c;
c = new Valentine("陳小安", 14) ;
c.greeting();
c = new Holiday("江大魚") ;
c.greeting();
10.
class Bicycle
{
private String type;
private String color;
private float price;
public String getType() { … }
public String getColor() { … }
public float getPrice() { … }
}
class RacingBike extends Bicycle
{
private String speeds;
public RacingBike(…..) { … }
public void printRacingBike() { … }
}
11.
abstract class Shape
{
public double x;
public double y;
abstract void area();
abstract void perimeter();
}
12.
class Polygon extends Shape
{
………
public void area() { … }
習題解答
}
13.
abstract class Vehicle
{
………
abstract void show();
}
class Cars extends Vehicle
{
………
public void show() { … }
}
class Trucks extends Vehicle
{
………
public void show() { … }
}
14.
abstract class Test
{
………
abstract void print();
}
class MidTerm extends Test
{
………
public void print() { … }
}
class Final extends Test
{
………
public void print() { … }
}
class Quiz extends Test
{
………
public void print() { … }
}
42
Java 2 程式設計範例教本
第 7 章:巢狀類別、多重繼承和套件
1.
巢狀類別強調類別之間的關係,成員類別稱為「內層類別」(Inner
Classes),例如:Employee 巢狀類別,如下所示:
class Employee // Employee 外層類別
{
…………
class Phone // Phone 內層類別
{
……………
}
…………
}
上述 Employee 類別擁有成員類別 Phone 的內層類別,Employee 是
巢狀類別的「外層類別」(Enclosing Class),Employee 物件的圖例,
如下圖所示:
上述圖例可以看出 Phone 內層類別的物件只能存在 Employee 外層
類別的物件中,list 是物件變數參考內層類別的 Phone 物件。
2. Students.class、Students$Exams.class
3.
「多重繼承」(Multiple Inheritance)是指一個類別能夠繼承多個父
類別,如下圖所示:
習題解答
上述圖例的類別 C 繼承類別 A 和 B,類別 E 繼承類別 C 和 D,分
別擁有 2 個父類別,一個類別繼承多個父類別稱為多重繼承。不過 Java
並不支援多重繼承(C++語言支援),但是提供相同目的的多重繼承 「介面」(Interface)。
介面(Interface)宣告是使用 interface 關鍵字,在類別繼承架構中
定義類別行為,內含常數和方法宣告,但是並沒有實作程式碼。
4.

介面並沒有實作程式碼,它和抽象類別的差異,如下所示:
抽象類別的方法可能只有宣告,但是仍然可以擁有一般方法,介面
的方法都只有宣告,而且一定沒有實作的程式碼。

介面不屬於類別的繼承架構,就算亳無關係的類別也一樣可以實作
同一個介面。

類別只能繼承一個抽象類別,但是可以同時實作多個介面。
不正確,正確的宣告如下所示:
interface Tax {
44
Java 2 程式設計範例教本
final double TaxRate = 0.06;
double calTax();
}
5. IPrint 介面繼承自 IShow,如下所示:
interface IPrint extends IShow
{
}
類別 Final 繼承自 Test 類別且實作 ShowInterface,如下所示:
class Final extends Test implements ShowInterface
{
}
6.
Java 語言的「套件」(Package)是一組相關類別和介面的集合,套
件能夠提供存取保護,如同其它程式語言的「函式庫」(Library),稱
為 Java API(Applications Programming Interface)。
API 是一種軟體的工具箱,Java 標準 API 是一個名為 java 的大型套
件,擁有數個子套件 lang、awt 和 io 等,每個子套件擁有許多的類別,
如下圖所示:
上述圖例是 java 套件架構,類似資料夾架構,只是分隔子元為”.”
句點,子套件 java.lang 包含基本的 Math 和 String 類別等,java.io 包含
輸入和輸出 I/O(Input/Output),java.awt 是 Java 的 GUI 元件等。
習題解答
換句話說,在 Java 程式檔案可以直接匯入上述套件定義的類別與
介面,然後繼承其類別和實作介面。其中 java.lang 屬於 Java 語言最基
礎的套件,Java 程式會自動匯入此套件的類別,所以在第 8 章可以直接
使用 java.lang 套件的 String 和 Math 等子套件。
7.
請參閱 7-3-2 和 7-3-3 節
8.
class LinkedList
{ ListNode front;
class ListNode
{ int value;
ListNode next;
// 建構子: 建立節點
public ListNode(int value) {
this.value = value; next = null;
}
public LinkedList(int value)
{
ListNode newnode;
// 建立節點物件
newnode = new ListNode(value);
firont = newnode;
}
}
9.
因為 Point.java 程式檔案的變數 x 和 y 是宣告成 protected 修飾子,
只可以在同一個類別、其子類別或同一套件中存取,所以編譯錯誤。如
果改為 public 修飾子就可以編譯成功,因為 public 擁有全域範圍,任何
類別都可以存取,包含子類別。
10.
因為 Point.java 程式檔案的變數 x 和 y 是宣告成 private 修飾子,
只可以在同一個類別存取,不可以在子類別存取,所以不只註解列編譯
錯誤,就連子類別都不可以存取這兩個變數。
46
Java 2 程式設計範例教本
11.
因為 Point.java 程式檔案的變數 x 和 y 沒有使用修飾子,其預設範
圍是只限同一個類別和套件中存取,但不包含不同套件的子類別,其存
取範圍比 protected 小,所以不只註解列編譯錯誤,就連不同套件的子類
別 ColorPoint 都不可以存取這兩個變數。
12. Java 語言的存取修飾子 public、private 和 protected 擁有不同的存取
權限範圍,筆者整理如下所示:

public:擁有全域範圍,任何類別都可以存取,包含子類別。

private:只可以在同一個類別存取,不可以在子類別存取。

protected:可以在同一個類別、其子類別或同一套件中存取。

沒有使用修飾子:預設範圍是同一個類別和套件中存取,但不包含
不同套件的子類別,protected 包含不同套件的子類別,所以其存取
範圍比 protected 小。
存取修飾子在 Java 程式可以使用的地方,筆者整理如下表所示:
修飾子
類別
成員變數
成員方法
建構子
public
可
可
可
可
private
可(巢狀)
可
可
可
protected
可(巢狀)
可
可
可
abstract
可
否
可
否
final
可
可
可
否
習題解答
上表的巢狀是指可以使用在內層類別。
第 8 章:字元、字串、數值類別與陣
列
1.
Java 的字串提供有 String 字串和 StringBuffer 字串緩衝器二種類別處
理字串資料。String 類別建立的字串物件只能讀取,而 StringBuffer 字串
緩衝器類別的字串就能夠新增、插入和刪除字串內容。
StringBuffer 字串緩衝區類別可以儲存的字元是是其字串容量,可
以使用 capacity()方法取得字串容量。
sb1 = new StringBuffer(25);
sb2 = new StringBuffer(25);
int result = sb1.compareTo(sb2);
2.
「陣列」(Array)是程式語言的一種基本資料結構,可以將相同資
料型態的變數集合起來,使用一個名稱代表,然後使用索引值存取變數
值,如下圖所示:
上述圖例的 tips 陣列屬於一種固定長度的結構,其長度在建立時已
經 決 定 , 每 一 個 「 陣 列 元 素 」 ( Array Element ) 是 從 「 索 引 值 」
(Index)0 開始到陣列長度減 1。
48
Java 2 程式設計範例教本
在 Java 語言的 Array 物件可以包含其它 Array 物件,這就是 Java
語言的二維陣列或多維陣列,如下所示:
int[][] scores = { { 54, 68 },
{ 67, 78 },
{ 89, 93 } };
上述程式碼宣告二維陣列 scores,並且指定元素值,在第一維共有
3 個元素,每一個元素是一個一維陣列{ 54, 68 }、{ 67, 78 }和{ 89,
93 },各擁有 2 個元素,所以總共有 3 X 2 等於 6 個元素,如下圖所
示:
scores[0][0]=54
scores[0][1]=68
scores[1][0]=67
scores[1][1]=78
scores[2][0]=89
scores[2][1]=93
上述二維陣列是使用初始方式建立陣列元素值,如果沒有使用初始
方式,可以使用 for 迴圈來建立二維陣列,如下所示:
String[][] users = new String[3][];
for ( i=0; i < users.length; i++)
users[i] = new String[2];
3.
float[] myArray = new float[10];
索引值序列:0、1、2、3
4. (1) 6
5.
(2) 23
測試的程式範例,如下所示:
public class Test
{
習題解答
// 主程式
public static void main(String[] args)
{
String str = "Java2 程式設計範例教本 2e-陳會安";
System.out.println(str.length());
System.out.println(str.charAt(10));
System.out.println(str.substring(11));
System.out.println(str.substring(5, 9));
}
}
其執行結果如下所示:
17
例
教本 2e-陳會安
程式設計
6.
測試的程式範例,如下所示:
(1)
public class Test
{
// 主程式
public static void main(String[] args)
{
String[] str = {"Java2 程式設計範例教本 2e", "陳會安"};
System.out.println(aMethod(str));
}
static String aMethod(String[] str)
{
if (str == null) return null;
String result = "";
for (int i = 0; i < str.length; i++)
result = result + str[i];
return result;
}
}
其執行結果如下所示:
50
Java 2 程式設計範例教本
Java2 程式設計範例 2e 教本陳會安
這個方法可以合併字串陣列中的各字串內容。
(2) 建立 365x24 的二維陣列。
7.
將參數字串先轉換成陣列,即使用一維字元陣列儲存字串內容,然
後使用走訪和陣列處理建立字串處理的類別方法,如下所示:

int strLen(String):走訪陣列即可計算出字串長度。

String strInsert(String1, String2, int):在轉換成陣列後,將第 1 個
字元陣列的 int 位置插入第 2 個陣列。

String strReplace(String1, String2, int) : 在 轉 換 成 陣 列 後 , 將
String1 陣列位置 int 開始取代成 String2 陣列。
8.
請參考第 8-6-4 節的程式碼將命令列參數轉換成整數,然後執行 12
小時與 24 小時制的時間轉換條件敘述運算子,如下所示:
hour = (hour >= 12) ? hour-12 : hour;
9.
請以走訪方式搜尋陣列中的最大值或最小值,如下所示:
static int getMax(int[] data,int len,int k) {
int max = 0;
for ( int i = 0; i < len; i++ ) // 搜尋迴圈
// 比較是否是鍵值
if ( data[i] > max ) max = data[i];
return max;
}
10.
請參考第 8-6-4 節的程式來修改 Ch8_6_1.java 程式碼
11.
請使用二層巢狀迴圈走訪二維陣列來計算每一列的總和和平均,2
個對角線陣列元素的索引值是相同的。
習題解答
12.
使用三層巢狀迴圈
第 9 章:Java Applet 與事件處理
1.
Java Applet 並不是完整的 Java 應用程式,所以並不能直接在作業系
統執行,而是需要透過瀏覽程式來執行 Java Applet,如果瀏覽程式支援
JVM 或安裝 Java Plug-in 外掛程式,就可以執行 Java Applet,如下圖所
示:
上述圖例在伺服端的 Java Applet 已經編譯成*.class 類別檔,在
HTML 網頁是使用<applet>標籤嵌入 Java Applet 類別檔,當客戶端瀏覽
程式請求伺服端擁有 Java Applet 的網頁時,*.class 和*.htm 檔案都會下
載到客戶端,然後在瀏覽程式執行 Java Applet。
Java Applet 程式是一個類別檔,並沒有主程式 main(),這是一個繼
承 Applet 的類別,然後實作或覆寫(Override)一些 Applet 方法。Java
Applet 程式的基本架構是繼承自 Applet 類別。
2.
Java Applet 類別檔 MyApplet.class,其尺寸的寬為 200,高為 200,
<applet>標籤如下所示:
<applet code="MyApplet.class" width=200 height=200>
</applet>
3. Applet、Graphics
52
Java 2 程式設計範例教本
4.
取得 HTML 參數 INC 和 OFFSET,並且將它轉換成整數 Integer。
5.
Java SDK 1.1 版 的 事 件 處 理 是 一 種 「 委 託 事 件 處 理 模 型 」
(Delegation Event Model),分為「事件來源」(Event Source)和處理
事件的「傾聽者」(Listener)物件,如下圖所示:
上述圖例的事件來源可能是 Component 物件的滑鼠、滑鼠移動和鍵
盤事件,或是 AWT 元件產生的選取或文字輸入事件,當事件產生時,
傾聽者可以接收事件然後進行處理,傾聽者是一個委託處理指定事件的
物件。
在 Java 事件來源物件產生的事件就是一個物件,這些事件物件都
屬於 AWTEvent 的子類別,AWTEvent 事件可以分為「低階事件」
(Low-level Events)和「語意事件」(Semantic Events)兩種。
6.
當使用者使用滑鼠按一下、進入、離開、按下或鬆開按鍵等操作
時,MouseEvent 的事件物件就會產生,此時委託處理事件的類別需要實
作 MouseListener 介 面 的 方 法 來 處 理 各 種 事 件 。 Java Applet 作 為
MouseEvent 事件傾聽者類別的架構,如下所示:
import java.applet.Applet;
import java.awt.Graphics;
import java.awt.event.*;
public class Ch9_4_2 extends Applet implements MouseListener
{
public void paint(Graphics g)
{
………
習題解答
}
public void init()
{
addMouseListener(this);
}
// 事件處理方法
public void mouseClicked(MouseEvent evt){ }
public void mouseEntered(MouseEvent evt){ }
public void mouseExited(MouseEvent evt){ }
public void mousePressed(MouseEvent evt){ }
public void mouseReleased(MouseEvent evt){ }
}
7.
使用 drawString()方法顯示文字和 drawRect()方法顯示方框
8.
public void paint(Graphics g)
{ for (int i=10; i <= 200; i = i+50)
for (int j = 10; j <= 200; j = j+50)
g.drawLine(i,10,j,60);
}
9.
for (int i=10; i <= 20; i = i+5) {
// 繪出正方形
g.drawRect(i, i, 100-2* i, 100-2*i);
// 繪出 X
g.drawLine(i,i,i+100-2* i, i +100-2*i);
}
10.
// 繪出大"*"符號
g.drawLine(0,0, 100, 100);
g.drawLine(0, 100, 100, 0);
g.drawLine(0, 50, 100, 50);
g.drawLine(50, 0, 50, 100);
// 繪出大的"%"符號
g.drawOval(25, 25, 10, 10);
g.drawLine(0, 100, 100, 0);
g.drawOval(75, 75, 10, 10);
54
Java 2 程式設計範例教本
11.
使用 drawOval()方法
12.
int key = evt.getKeyCode();
13.
請自行編譯和測試書附光碟 Ch09/Ch9_5_5.java 和 Ch9_5_5.htm 的
Java Applet 程式範例。
14.
請參考 Ch9_5_4.java 和 Ch9_5_5.java 程式
第 10 章:Swing 套件的容器元件與
版面配置
1.
Swing 套件的類別是定義在名為 javax.swing 套件,第 9 章介紹的
AWT 元件屬於 JDK 1.0 和 1.1 版的 GUI 元件,在 Java 2 平台提供全新
的 Swing 元 件 來 取 代 AWT , 大 部 分 的 Swing 元 件 都 是 繼 承 自
JComponent,其元件名稱都是以”J”字母開頭,如下圖所示:
習題解答
從上述繼承架構可以看出 Swing 是繼承自 AWT 的 Container 和
Component 類別,所以仍然使用 AWT 的版面配置、事件物件和傾聽者
類別,只是取代 GUI 元件,提供一組全新的 GUI 元件 JComponent。
換句話說,原來 AWT 的元件在 Swing 大都擁有對應元件。例如:
AWT 的 java.awt.Button,在 Swing 是對應 javax.swing.JButton,不過
AWT 的 Canvas 並沒有 JCanvas,而是被 JPanel 取代。
Swing 應用程式的架構像是在一個大盒子中放入多個小盒子,首先
將 Swing 套件的各種 GUI 元件 JButton 和 JLabel(在第 11 章詳細說明)
新增到中間層容器元件。例如:第 10-3-1 節的 JPanel,然後將 JPanel 新
增到最上層容器類別 JFrame,JFrame 是一種擁有標題列的視窗元件,
如下圖所示:
上述圖例位在最外面的容器類別決定建立哪一種 Swing 應用程式,
JFrame 是視窗應用程式,如果是 JApplet,就是包含 Swing 元件的 Java
Applet。
2. TestFrame 類別 Swing 應用程式的程式碼,如下所示:
import javax.swing.*;
import java.awt.*;
import java.awt.event.*;
public class TestFrame extends JFrame
{ ………
56
Java 2 程式設計範例教本
public static void main(String[] args)
{ TestFrame app = new TestFrame();
app.addWindowListener(new WindowAdapter()
{ public void windowClosing(WindowEvent evt)
{ System.exit(0); }
});
app.setSize(300,100); // 設定視窗尺寸
app.setVisible(true);
// 顯示視窗
}
}
3.
在 AWT 的 java.awt.event 套件提供 XXXAdapter 改編者類別,如下
表所示:
XXXAdapter 類別
實作的傾聽者介面
ComponentAdapter
ComponentListener
ContainerAdapter
ContainerListener
FocusAdapter
FocusListener
KeyAdapter
KeyListener
MouseAdapter
MouseListener
MouseMotionAdapter
MouseMotionListener
WindowAdapter
WindowListener
傾聽者類別如果是繼承自上表的改編者 Adapter 類別,就只需實作
所需的方法,而不用實作全部方法。例如:第 10-1-2 節程式範例的主程
式 main()使用 WindowListener 事件傾聽者,這個介面一共有 7 個方法,
但是我們只實作 windowClosing()一個方法,如下所示:
app.addWindowListener(new WindowAdapter()
習題解答
{
public void windowClosing(WindowEvent evt)
{ System.exit(0); }
});
4. JFrame、JDialog 和 JApplet。
5. ContentPane
6.
「 版 面 配 置 管 理 員 」 ( Layout Manager ) 是 用 來 編 排 置 於
ContentPane 和中間層容器的 Swing 元件,版面配置管理員可以控制容
器內元件的尺寸和位置,不同的版面配置管理員擁有不同預設的編排方
式,只需依照需求選擇使用的版面配置管理員,就可以編排出漂亮的
GUI 介面。
JComponent 類別的 setBorder()方法可以替元件新增框線。
7.
JOptionPane.showMessageDialog(jpane, "對不起!您的答案是錯誤的",
"錯誤訊息", JOptionPane.ERROR_MESSAGE);
8.
c.add(new JLabel("(北)",JLabel.CENTER), BorderLayout.NORTH);
c.add(new JLabel("(中)",JLabel.CENTER), BorderLayout.CENTER);
c.add(new JLabel("(西)",JLabel.CENTER), BorderLayout.WEST);
c.add(new JLabel("(南)",JLabel.CENTER), BorderLayout.SOUTH);
c.add(new JLabel("(東)",JLabel.CENTER), BorderLayout.EAST);
9.
10.
請參考第 10-5 節的程式範例
請參考第 10-4-4 節的程式範例
11.
c = getContentPane();
58
Java 2 程式設計範例教本
c.setBackground(Color.lightGray);
c.setBackground(Color.white);
12.
TitledBorder titledLine = BorderFactory.createTitledBorder(redLine,
"標題",TitledBorder.CENTER,TitledBorder.BOTTOM);
13.
請參考本章的 Ch10_1_2.java 程式範例新增 3 個 JButton 按鈕和 1
個 JLabel 元件,然後使用亂數產生 3 個 1~14 之間的整數,使用 if 條件
判斷是按下哪一個按鈕,如下所示:
public void actionPerformed(ActionEvent evt)
{
if (evt.getSource() == button1)
{
label.setText(“按鈕值” + num1);
}
if (evt.getSource() == button2)
{
label.setText(“按鈕值” + num2);
}
if (evt.getSource() == button3)
{
label.setText(“按鈕值” + num3);
}
}
14.
請參考習題 11 和 13 的程式片斷
第 11 章:Swing 的圖形介面元件
1. JComponent。
2. ActionListener、actionPerformed()
3.
JCheckBox 核取方塊元件繼承自 JToggleButton,屬於 AbstractButton
的子類別,這個元件是一個開關,按一下可以更改狀態值為 true 或
習題解答
false,顯示的外觀為是在核取方塊中打勾,其初始值為 false,即沒有打
勾 , JRadioButton 選 項 鈕 元 件 也 是 繼 承 自 JToggleButton , 屬 於
AbstractButton 的子類別,通常為一組選項鈕的單選題,在一組選項鈕
中,按一下選項鈕就可以更改狀態值為 true 或 false,在一組選項鈕只能
有一個選項鈕為 true。
4.
Font[] font = new Font[5];
font[0] = new Font("Serif", Font.BOLD, 14);
font[1] = new Font("SansSerif",Font.BOLD+Font.ITALIC,24);
font[2] = new Font("標楷體", Font.PLAIN, 20);
font[3] = new Font("新細明體", Font.PLAIN, 30);
font[4] = new Font("細明體", Font.ITALIC, 36);
5.
請參考第 11-2 節程式碼建立 Swing 應用程式,然後使用第 2-3-2 節
的公式將攝氏轉成華氏,或華氏轉成攝氏溫度。
6.
請參考程式範例 Ch11_1_5.java。
7.
請參考第 11-3 節建立功能表,然後使用亂數產生 1~100 之間的整
數,然後參考第 11-2 節建立輸入整數的文字方塊,使用 if 條件判斷輸
入值太大或太小,如下所示:
JTextField s = (JTextField)evt.getSource();
showLabel.setText("輸入資料 : " + s.getText());
int value = Integer.parseInt(s.getText());
if ( value > target ) resultLabel.setText(“太大”);
else if ( value < target ) resultLabel.setText(“太小”);
else resultLabel.setText(“猜中”);
8.
請參考第 11-2-2 節取得 JTextArea 元件的文字內容後,使用字串處
理函數計算文字列數、字數,然後使用 JOptionPane 訊息視窗顯示計算
結果
60
Java 2 程式設計範例教本
9.
請參考第 11-1-6 節的程式範例建立 JSlider 元件取得選擇的身高 H
(公尺)和體重 W(公斤)值,然後就可以使用 W/H2 公式計算 BMI
值,使用訊息視窗或 JLabel 元件來顯示結果
10.
請使用迴圈判斷金額是否大於等於 5,每執行一次迴圈就依序計
算出可以轉換成多少張 1000、500 元、200、100 元紙鈔和 50、10、5、
1 元的硬幣
while ( amout >= 5 ) {
if ( amout > 1000 ) {
value = amount / 1000;
amount = amount % 1000;
}
…………..
}
11.
請參考第 11-4 節來修改程式範例 Ch11_3_2.java
12.
請請參考第 11-3 節來改寫 Ch11_5.java 的範例程式
13.
請參考 Ch11_1_5.java 和 Ch11_5.java 範例程式
14.
請參考本節程式範例和 Windows 作業系統附屬應用程式的標準型
小算盤
第 12 章:繪圖與多媒體
1.
如 果 縮 小 或 放 大 視 窗 , 讀 者 會 發 現 使 用 getGraphics() 方 法 取 得
Graphic 物件所繪出的圖形不見了,這是因為程式碼不是在 paint()或
paintComponent()方法,所以系統重繪圖形時,並不包含此圓形。
習題解答
2.
元件的繪圖操作大都是呼叫 paint()方法來完成,paint()方法能夠在
調整視窗尺寸,例如:縮小和放大元件的視窗)等使用者的操作,或是執
行 setText()等方法改變元件內容時,自動重新呼叫 repaint()方法重繪出
調整後的圖形和元件。
如果不是在 paint()方法,Java 程式碼需要使用 getGraphics()方法取
得 Grphics 物件後,在 Graphics 物件繪出所需圖形,如下所示:
Graphics g = app.getGraphics();
g.setColor(Color.green);
g.fillOval(100, 100, 40, 40);
3.
左上角、getWidth()、getHeight()
4.
紅、綠、藍
5.
FontMetrics 物件可以取得字串和字型細部定位尺寸,以便在畫布上
能夠準確編排文字內容,相關字型的細部尺寸,如下圖所示:
上述字型是以 Baseline(基線)為準,上方稱為 Ascent,下方稱為
Descent,Leading 是頂端線間的高度。
6.
請修改第 12-1-4 節的程式範例的 UserPanel 類別
62
Java 2 程式設計範例教本
7.
請參考第 12-2-5 節的程式範例,使用 fillPolygon()方法繪出藍色填
滿的多邊形,如下所示:
int[] xs = {15, 80, 100, 150, 200};
int[] ys = {80, 30, 40, 120, 250};
g.fillPolygon(xs, ys, xs.length);
8.
請參考第 12-4-1 節修改 Ch12_2_1.java 範例程式
9.
請參考第 12-4-1 節修改 Ch12_2_2.java 範例程式
10.
請參考第 12-4-1 節和第 12-2-4 節和第 12-2-5 節的繪圖方法
11.
請參考第 12-4-1 節的程式範例
12.
請參考第 12-4-1 和 12-4-2 節的程式範例
第 13 章:Java 的例外處理
1. Java 的例外處理架構是一種您丟我撿的架構,當 JVM 執行 Java 程式
有錯誤發生時,就會產生例外物件,有了例外,JVM 開始尋找是否有方
法可以處理,一種是在方法上加上例外處理的程式敘述來處理例外(在
第 13-2 節說明),或是將例外丟給其它方法來處理(在第 13-3 節說
明),如下圖所示:
習題解答
上述圖例在執行 Java 程式時,從 main()方法呼叫 methodA()方法,
接著呼叫 methodB()方法,最後呼叫 methodC()方法,呼叫過程是存入稱
為「呼叫堆疊」(Call Stack),這是一種先進後出的資料結構,用來儲
存呼叫方法的狀態資料,以便返回還原成呼叫時的狀態。
當 methodC()方法發生錯誤產生例外物件 A,JVM 倒過來找尋方法
是否擁有例外處理,首先是 methodC()和 methodB(),因為沒有例外處
理,所以例外會傳遞給 methodA(),在此方法擁有例外處理 A,所以可
以處理例外物件 A。
不只如此,方法本身也可以自行丟出例外物件,例如:methodB()
丟出例外 B,同樣也需要找尋是否有例外處理的方法可以進行處理,以
此例雖然 methodB()擁有例外處理,但是因為例外類型不同,直到 main()
方法才找到正確的例外處理。
2.
雖然例外也是一種錯誤情況,只是這種錯誤沒有嚴重到需要終止程
式的執行,我們可以使用例外處理防止程式執行終止,並且作一些補
救。
64
Java 2 程式設計範例教本
例外處理的目的是為了讓程式能夠更加「強壯」(Robust),如此這
算程式遇到不尋常的情況,也不會造成程式「崩潰」(Crashing),甚至導
致整個系統當機的情況。
3. Error、Exception
4.
多、0 到 1 個
5. ArithmeticException 和 ArrayIndexOutOfBoundsException 物件。
6.
static double Test(double a, double b)
throws IllegalArgumentException
try
{
}
catch( IllegalArgumentException e )
{ // 處理 IllegalArgumentException 例外
System.out.println("例外說明: "+e.getMessage());
System.out.print("例外原因: ");
e.printStackTrace();
}
7. print3N1(int)方法丟出例外物件的程式碼,如下所示:
if ( param <= 0 )
{ // 丟出 IllegalArgumentException 例外
throw new IllegalArgumentException("參數小於 0 或等於 0!");
}
if ( param > 1000 )
{ // 丟出 ArithmeticException 例外
throw new ArithmeticException("參數大於 1000!");
}
8.
請參考第 13-4 節的程式碼
第 14 章:基本輸出入與檔案處理
習題解答
1.
串流(Stream)觀念最早使用在 Unix 作業系統,串流模型如同水管
的水流,當程式開啟一個來源的輸入串流(例如:檔案、記憶體和緩衝
區等),Java 程式可以從輸入串流依序讀取資料,如下圖所示:
上述圖例在程式左半邊是讀取資料的輸入串流,程式輸出資料是在
右半邊開啟一個目的(同樣是檔案、記憶體和緩衝區等)的輸出串流,
然後將資料寫入串流。例如:檔案複製程式開啟來源檔案的輸入串流和
目的檔案的輸出串流,接著從來源串流讀取資料後,馬上寫入輸出串流
的目的檔案,就可以完成檔案複製。
換句話說,串流模型並沒有考慮資料來源、型態、從哪來或從哪
去,程式只是如水流般的依序讀取資料,然後依序寫入資料。
java.io 套件
2.
Java 的 java.io 套件提供多種串流類別,基本上,Java 串流類別分成
兩大類:「字元串流」(Character Stream)和「位元組串流」(Byte
Stream),然後再加區分為輸入/輸出 2 種串流類別。
字元串流(Character Stream)
字元串流是 Java 1.1 版才支援的串流類別,這是一種適合「人類閱
讀」(Human-readable)的串流,Reader/Writer 兩個類別分別讀取和寫
入 16 位元的字元資料,屬於字元串流的父抽象類別。
66
Java 2 程式設計範例教本
在 java.io 套件提供多種繼承自 Reader/Writer 的子類別,提供各種
情況的串流資料處理,其名稱都是使用 Reader 和 Writer 結尾,例如:

BufferReader/BufferWriter:處理緩衝區 I/O。

InputStreamReader/OutputStreamWriter:InputStreamReader 在讀取位
元組資料後,可以將它轉換成字元資料,OuputStreamWriter 是將字
元轉換成位元組資料。

FileReader/FileWriter:處理檔案 I/O。
位元組串流(Byte Stream)
位元組串流是一種「電腦格式」(Machine-formatted)串流,可以
讀取和寫入 8 位元的位元組資料,也就是處理二進位資料的執行檔、圖
檔 和 聲 音 等 , 其 父 抽 象 類 別 的 輸 入 / 輸 出 串 流 名 稱 為
InputStream/OutputStream 類別。
同樣的,在 java.io 套件擁有多種繼承自 InputStream/OutputStream
的子類別,其名稱都是使用 InputStream/OutputStream 結尾,例如:

FileInputStream/FileOutputStream:處理檔案 I/O。

DataInputStream/DataOutputStream:讀取和寫入 Java 基本資料型態
的資料。
BufferInputStream/BufferedOutputStream:處理緩衝區 I/O。
3. java.lang 套件
習題解答
4.
「循序存取串流」(Sequential Access Streams),只能順序讀取和
寫入檔案內容,而「隨機存取檔案」(Random Access File)則可以非順
序和隨機存取檔案的內容,如同是一個檔案的陣列,可以使用索引存取
元素,這個索引稱為「檔案指標」(File Pointer)。
5.
請參考第 11-4-1 節的 JFileChooser 元件和第 14-4-3 節程式碼
6.
請參考第 8-6-4 節取得命令列參數、第 8-5-1 節產生亂數,然後參考
第 14-4-1 節將整數以字元方式寫入文字檔案
7.
請參考第 11-1-5 節來修改 Ch14_2_6.java 程式
8.
請參考第 11-3 節建立功能表,第 11-4-1 節 JfileChooser 選擇檔案,
以便使用第 14-2 節的 File 物件執行檔案和資料夾處理
9.
請參考第 11 章和第 14 章的程式碼,使用 JTextArea 元件編輯文字
內容
10.
請參考 Ch14_5_2.java 範例程式
11.
請參考第 14-6 節修改 Ch14_6.java 程式範例
12.
請使用 Java 設計下列檔案處理工具程式,如下所示:

FileCat.java:請使用第 14-4-3 節的檔案複製程式來合併檔案。

BackupDir.java:請使用第 14-2-1 節取得目錄下的檔案清單,然
後使用第 14-4-3 節的檔案複製程式來備份檔案。

FileComp.java:請同時開啟 2 個文字檔案,然後讀取內容,以
字串物件的方法來比較內容。
68
Java 2 程式設計範例教本

FileCount.java:使用每次讀取一列的方法來計算列數。

FileList.java:每次讀取一列的程式碼加上列號後,寫入輸出檔
案即可。
第 15 章:JDBC 資料庫處理
1.
Java 應用程式可以使用 JDBC 的 JDBC-ODBC 橋接驅動程式,透過
JDBC-ODBC 驅 動 程 式 存 取 ODBC 資 料 來 源 的 關 聯 式 資 料 庫 系 統
Access,如下圖所示:
上述圖例的「ODBC」(Object Database Connectivity)是一種中介
軟體,提供應用程式一種標準的資料庫存取方式,能夠存取各種作業系
統上執行的不同資料庫系統。
習題解答
換句話說,應用程式是透過 ODBC 來存取資料庫,所以並不用考
慮隱藏背後的是哪一種資料庫系統,因為 ODBC 能夠將各種不同資料庫
系統的資料都轉換成 ODBC 的資料存取方式。
不過,Java 應用程式並沒有辦法直接存取 ODBC,需要額外使用
JDBC-ODBC 驅動程式進行轉換,如此 Java 程式才能夠存取 ODBC 系統
資料來源的資料庫。
2. JDBC 驅動程式的可以分為四種,如下所示:

JDBC-ODBC 橋接驅動程式(JDBC-ODBC Bridge):Java 程式可以
存取微軟 ODBC 資料來源的資料庫系統,本章就是以 JDBC 驅動程
式為例。

原生 API 的 Java 驅動程式(A Native-API Partly Java Driver):將
Java 程式的 JDBC 呼叫轉換成專屬資料庫系統的原生 API 呼叫。

Java 網路協定驅動程式(A Net-protocol All Java Driver):將 Java
程式的 JDBC 呼叫轉換成資料庫系統專屬的網路協定,再由伺服器
轉換成資料庫系統的 API 呼叫。

Java 原生通訊協定驅動程式(A Native-protocol All Java Driver):將
Java 程式的 JDBC 呼叫直接轉換成資料庫系統原生通訊協定的 API
呼叫,以便客戶端可以直接連線資料庫伺服器。
3. ResultSetMetaData、ResultSet
4.
「 SQL 」 ( Structured Query Language ) 為 「 ANSI 」 ( American
National Standards Institute)標準的資料庫語言,SQL 指令語法可以用來
查詢、新增、刪除和更新資料庫的記錄,目前 Access、SQL Server、
70
Java 2 程式設計範例教本
DB2、MySQL、MySQL MaxDB、Oracle 和 Sybase 等資料庫管理系統都
以 ANSI 的 SQL 語言作為標準的資料庫語言。
早在 1970 年,E. F. Codd 建立關聯性資料庫的觀念,同時提出構想
的資料庫語言,這是一種完整和通用的資料存取方式,雖然在當時並沒
有真正建立語法,但這就是 SQL 的源起。
1974 年一種稱為 SEQUEL 的語言,這是 Chamberlin 和 Boyce 的作
品,它建立 SQL 原型,IBM 稍加修改後作為其資料庫 DBMS 的資料庫
語言,稱為 System R,1980 年 SQL 的名稱正式誕生,從那天開始,
SQL 逐漸壯大成為一種標準的關聯式資料庫語言,SQL 語言的指令可以
分為三大部分,如下表所示:

資料定義語言(Data Definition Language,DLL):建立資料表、索
引和視界(Views)等,並且定義資料表的欄位。

資料操作語言(Data Manipulation Language,DML):屬於資料表
記錄查詢、插入、刪除和更新指令。

資料控制語言(Data Control Language,DCL):屬於資料庫安全設
定和權限管理的相關指令。
5. executeUpdate()、executeQuery()
6.
請參考相關書籍,啟動 Office 的 Access 建立同學通訊錄資料庫
address.mdb,內含資料表 Students
7.
請參考第 15-3-1 節程式碼
8.
請參考第 15-3-3 節程式碼
習題解答
9.
請參考第 15-4 節的程式碼
10.
請參考第 15-4-3 節和第 15-5-3 節的程式碼
11.
請參考第 15-7 節的專案
12.
請參考第 15-5-2 節的程式碼來修改第 15-7 節圖書資料管理系統新
增更新圖書記錄資料的功能
第 16 章:Java 的執行緒
1.
「 執 行 緒 」 ( Thread ) 也 稱 為 「 輕 量 行 程 」 ( Lightweight
Process),其執行過程類似上述程式執行,只是執行緒不能單獨存在或
執行,一定需要隸屬於一個程式,由程式啟動執行緒,如下圖所示:
上述圖例的 Java 程式產生一個執行緒,這個執行緒是在程式中執
行,可以將它視為是在程式中執行的小程式。
72
Java 2 程式設計範例教本
換句話說,如果程式碼本身沒有先後依存關係。例如:因為 b()方
法需要使用到 a()方法的執行結果,所以需要在執行完 a()方法後,才能
執行 b()方法,此時 a()方法和 b()方法並不能同時執行,也就無法使用 2
個執行緒來同步執行。
如果程式能夠分割成多個同步執行緒來一起執行,這種程式設計方
法稱為「平行程式設計」(Parallel Programming),如下圖所示:
上述圖例的程式擁有 2 個執行緒且同步執行,程式擁有多個執行流
程,能夠在同一個程式中同時執行來增加程式的執行效率。
目前的作業系統都強調「多工」(Multitasking)。例如:微軟的
Windows 作業系統屬於一套多工的作業系統,可以同時執行小畫家、記
事本和小算盤等多個應用程式。
不同於作業系統的多工,「多執行緒」(Multithreaded)是指在單
一應用程式擁有多個執行流程。例如:Web 瀏覽程式可以在下載網頁檔
案的同時顯示動畫、播放音樂或捲動視窗瀏覽網頁內容。
習題解答
2.
Java 執行緒是建立 Thread 類別的物件,一共有 2 種方式建立多執行
緒應用程式,如下所示:

實作 Runnable 介面。

繼承 Thread 類別。
3. Runnable、run()
4.
因為執行緒可以用來控制文字移動或動畫效果,所以我們可以使用
執行緒建立 Java Applet 的動畫效果。
5.
在執行緒間並沒有任何關係,簡單的說,執行緒的目的只是為了加
速程式執行。另一種情況是執行緒間擁有生產和消費者的關係或是同時
存取相同資源,當有此情況,就需要考量「同步」(Synchronization)
問題。
生產者和消費者模型(Producer/Consumer Model)
生產者和消費者模型是指一個執行緒產生資料,稱為生產者,另一
個執行緒讀取生產者產生的資料,稱為消費者,產生的資料是儲存在共
用的資料儲存緩衝區稱為「佇列」(Queue),這是一種先進先出的資
料結構,如下圖所示:
74
Java 2 程式設計範例教本
上述圖例的生產者將產生資料送入佇列的一端,消費者可以從佇列
的另一端讀取資料。
6. synchronized
7.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
習題解答
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
1225
8.
long startTimer = evt.getWhen();
…………..
long endTimer = evt.getWhen();
double currentSeconds = (endTimer - startTimer)/1000.0;
9.
在第 16-3 節加大佇列容量,就不容易產生兩種情況需要特別處理,
如下所示:

佇列空了:如果佇列空了,消費者需要等待生產者產生資料。

佇列滿了:如果佇列滿了,表示已經沒有地方儲存,生產者需要等
待消費者讀取資料。
static final int MAXQUEUE = 5;
10.
請參考第 16-4 節的程式碼來修改 Ch12_4_1.java 和 Ch12_4_2.java
第 17 章:Java Collections 集合物件
76
Java 2 程式設計範例教本
1.
「集合物件」(Collections)是指一組相關的物件集合,將這組物
件集合視為單一物件,在集合物件中的物件稱為「元素」
(Elements),集合物件有很多種,其儲存的元素可能允許重複,有些
集合物件的元素會進行排序,在舊版 Java 技術是指 Vector 和 Hashtable
物件。
JDK 1.2 之 後 的 版 本 提 供 全 新 的 集 合 物 件 架 構 , 稱 為 Java
Collections Framework,這是用來儲存和處理集合物件的統一軟體架
構,其組成如下所示:

集合介面(Collection Interface):一組定義完善的 Java 介面,提供
處理集合物件的標準介面,其目的是讓集合物件擁有一致的操作方
式,包含:Collection、Set、SortedSet、List、Map 和 SortedMap 介
面。

實作(Implementations):實作集合介面的類別,稱為「具體類別」
(Concrete Class),對比抽象類別,這是可以使用 new 運算子建立
實例的類別,以實作的集合介面來區分,常用的介面如下表所示:
介面
具體類別
Set
HashSet
SortedSet
TreeSet
List
ArrayList、LinkedList、Vector
Map
HashMap、Hashtable
SortedMap
TreeMap
習題解答

演算法(Algorithms):當物件實作集合介面,其實作的一些多形方
法,可以執行集合物件元素的搜尋與排序等演算法。
「泛型 Java」(Generic Java)是 JDK 5.0 版在 Java 語法上的重大
變革,提供類似 C++語言的「樣版」(Templates)語法,新增編譯階段
的集合物件型態檢查功能,可以減少程式碼中取出元素所需的大量型態
轉換。
例如:舊版集合物件在建立 HashSet 物件時,因為存入的是 Object
物件,所以我們可以存入 Byte、Float 和 String 等各種不同資料型態的
元素,不過,當集合元素取出元素時,程式設計者需要自行記得存入的
元素是哪一種資料型態,然後將 Object 物件型態轉換成指定的資料型
態,如下所示:
Customer temp;
Iterator iterator = tset.iterator();
temp = (Customer) iterator.next();
上述程式碼在使用 Iterator 介面取出 TreeSet 集合物件 tset 的元素
時,需要將它型態轉換成 Customer 類別的物件,才能指定給 temp 物件
變數,程式設計者需要自行記錄儲存在 tset 集合物件的元素是 Customer
物件。
泛型 Java 可以使用「泛型型態」(Generic Types)來擴充 Java 語
言,簡單的說,就是在建立集合物件時,以泛型型態指定集合物件儲存
元素的資料型態,如下所示:
HashSet<Btype> hset = new HashSet<Byte>();
HashSet<Float> hset = new HashSet<Float>();
HashSet<String> hset = new HashSet<String>();
上述程式碼在 HashSet 類別之後,使用”<”和”>”括起資料型態就是
泛型型態,它是用來指定集合物件儲存元素的資料型態,以便 Java 編譯
78
Java 2 程式設計範例教本
程式可以自行追蹤記錄元素的資料型態,換句話說,在 Java 程式取出元
素時,就不需自行使用程式碼來執行型態轉換。
2.
集合介面、實作和演算法
3. Set 和 List 子介面
4. ArrayList、LinkedList
5. SortedSet 介面、Map 介面、TreeSet 類別和 TreeMap 類別
6.
List 和 Set 介面都屬於 Collection 介面的子介面,其最大差異在於實
作 List 介面的集合物件允許儲存的元素重複。
7. Iterator 和 ListIterator 介面
8. ListIterator 介面
9.
class Stack { // 堆疊類別的宣告
// 建立 LinkedList 物件
private LinkedList<Integer> llist =
new LinkedList<Integer>();
// 新增堆疊元素
public void push(Integer obj) {
llist.addFirst(obj);
}
// 取出堆疊元素
public Integer pop() {
Integer obj = llist.getFirst();
llist.removeFirst();
return obj;
}
public boolean isStackEmpty() {
return (llist.size()>0 ? false : true);
習題解答
}
}
10.
請參考習題 9 的解答
第 18 章:Java 網路程式設計
1.
TCP/IP 通訊協定
TCP/IP 是一組通訊協定的名稱,這是 Internet 網際網路使用的通訊協
定,稱為一組是因為 TCP/IP 代表著十數種通訊協定,而以該組協定中
最重要的兩個協定「TCP」(Transmission Control Protocol)和「IP」
(Internet Protocol)為名。
TCP/IP 是 Internet 成千上萬台電腦間的共通語言,如同人類溝通時
使用的語言一般,Internet 的電腦主機間彼此藉著 TCP/IP 互相交換電腦
資料,至於如何找到電腦則是使用 IP 位址和網域名稱。
IP 位址(IP Address)
在 Internet 的每部電腦都擁有一個唯一的位址,Internet 的定址系統
採用的方式是指定每一台電腦一個號碼,稱為 IP 位址,長度為四個位
元組,十進位格式,如下所示:
dec3.dec2.dec1.dec0
上述 IP 位址的格式是在四個數字間使用小數點「.」隔開,例如:
HiNet DNS 伺服器的 IP 位址是 168.95.192.1。
80
Java 2 程式設計範例教本
網域名稱(Domain Name)
IP 位址對於 Internet 的電腦之間識別電腦已經足夠了,但是從使用
者的角度而言,記憶四個數字並不是一件容易的事,為了方便記憶電腦
的位址,我們給予 IP 位址一個英文縮寫的網域名稱。
為了管理 Internet 上成千上萬的電腦,網域名稱使用樹狀階層架構
來分門別類,1983 年「網域名稱系統」(Domain Name System,縮寫為
DNS)使用樹狀階層結構對映網域名稱,在樹狀階層結構的最上層分為
九大類 edu、com、gov、mil、org、net、int、apra 和國碼(依 ISO 標準
定義,例如:tw 代表台灣)。
2.
URL 類別的物件是 WWW 服務的資源物件,每一個 URL 物件就是
URL 位址,也就是瀏覽程式在【網址】欄輸入的位址字串。
Socket 類別可以透過 TCP/IP 連接一些常用的 Internet 服務,然後向
這些服務送出指令字串,就可以取得所需的資訊。常見的 Internet 服
務、埠號和說明,如下表所示:
服務名稱
埠號
說明
echo
7
伺服端只是將客戶端傳送的資料,原封不動的送回
discard
9
無論客戶端傳送什麼資料,伺服端都直接捨棄
daytime
13
傳回伺服器的日期和時間
ftp
21
FTP 服務
telnet
23
Telnet 服務
習題解答
smtp
25
SMTP 寄送郵件服務
whois
43
Whois 服務
finger
79
Finger 服務
http
80
WWW 服務
pop3
110
POP3 郵件接收服務
nntp
119
News 新聞服務
Java 語言也可以使用 SeverSocket 類別自行撰寫伺服器程式,如下
所示:
ServerSocket server = new ServerSocket(PORT);
while (true)
{
Socket socket = server.accept();
………
}
上述程式碼在指定埠號建立 ServerSocket 物件後,開始等待客戶端
使用相同埠號的連線請求,while 迴圈使用 accept()方法接受客戶端連
線,在傳回 Socket 物件建立連線後,即可建立串流進行通訊。
3.
Java 網路應用程式是使用 java.net 套件的類別,可以分成 2 種層次,
如下所示:
高階的 URL 類別
URL 類別的物件是「WWW」(World-Wide Web)的 URL 網址,
全名是「萬用資源定址器」(Universal Resource Locator),這個類別提
供 多 種 方 法 能 夠 剖 析 URL 網 址 , 並 且 支 援 「 HTTP 」 ( HyperText
82
Java 2 程式設計範例教本
Transfer Protocol)通訊協定,能夠連線 Web 網站且取得 HTTP 標頭資
料,或是直接下載網頁檔案。
低階的 Socket 類別
Socket 類別是用來建立不同程式的網路連線,以便 Java 程式可以透過網
路 連 線 到 其 它 Java 程 式 或 Internet 服 務 , 建 立 「 主 從 架 構 」
(Client/Server)的網路應用程式。
4. 80、25、110
5.
請參考第 14-4-2 節的程式碼來擴充 Ch18_3_3.java 範例程式
6.
請參考第 10、11 章和第 18-4-3~18-4-5 節的 SMTP 和 POP3 程式範
例
7.
請參考第 14-4-2 節的程式碼來擴充第 18-5 節的範例程式
8.
請客戶端程式新增 Swing 元件輸入使用者名稱,將使用者名稱傳送
到伺服端程式,以便使用集合物件儲存使用者清單來傳送到各客戶端聊
天室程式
第 19 章:Java Servlet 程式設計
1.
Servlet 程式不同於 Java Applet 程式是將類別檔案下載到瀏覽程式的
電腦執行。Servlet 程式可以擴充 Web 伺服器的功能,這是一種在伺服
器電腦執行且由伺服器控制下執行的程式檔。
習題解答
Servlet 是 Java 技術的標準擴充,Java Servlet API 是 Java Servlet 程
式所需的類別函式庫,一共有 javax.servlet 和 javax.servlet.http 兩個套
件,其最主要的功能是處理客戶端的使用者請求,如下圖所示:
上述圖例的瀏覽程式請求網頁或表單<form>標籤將使用者輸入的資
料送到 Web 伺服器,Web 伺服器將資料送給 Servlet 程式,在執行
Servlet 程式存取資料庫記錄或檔案,最後使用串流輸出成 HTML 文件
的回應資料,經由 Web 伺服器送回瀏覽程式,這就是我們看到的執行
結果。
Java Servlet 的執行是由 Web 伺服器的 Servlet 引擎所控制,Servlet
引擎載入 Servlet、執行 Servlet 和刪除 Servlet 的過程,就是在依序執行
init()、service()和 destroy()方法。執行過程的相關方法說明,如下表所
示:
方法
說明
void init()
如果是第一次請求或 Servlet 尚未載入,就呼叫 init()方
法載入 Servlet,除非刪除 Servlet,否則都不會再次呼
叫此方法
84
Java 2 程式設計範例教本
void service()
如果 Servlet 已經載入,就呼叫 service()方法來處理請
求,service()方法會呼叫其它 doXXX()方法來處理不同
的 HTTP 請求
void doGet()
處理 HTTP 的 GET 和 HEAD 請求
void doPost()
處理 HTTP 的 POST 請求
void doPut()
處理 HTTP 的 PUT 請求
void doDelete()
處理 HTTP 的 DELETE 請求
void destroy()
當 Servlet 閒 置 一 段 時 間 或 伺 服 器 關 機 , 就 呼 叫
destroy()方法刪除 Servlet
一般來說,HTTP 請求的 Servlet 程式就是覆寫指定請求的 doXXX()
方法來取得輸入或輸出資料,而主要就是:doGet()和 doPost()方法。
2.
請參閱第 19-1-2 節
3.
請參考 Ch19_2_3.java 程式碼
4.
Web 伺服器的環境變數就是所謂的 CGI 變數,這些變數值是一些狀
態資訊,屬於 HTTP 請求的標頭檔(HTTP Request Header)資訊,可以
提供客戶端請求和伺服器的相關資訊。
HttpServletRequest 和 ServletRequest 介面物件的方法可以取得系統
環境變數,常用的環境變數和對應方法,如下表所示:
環境變數名稱
方法
說明
習題解答
AUTH_TYPE
getAuthType()
伺服端的認證方法
CONTENT_LENGTH
getContentLength()
傳送給伺服器內容的長度
CONTENT_TYPE
getContentType()
傳送內容的資料類型
DOCUMENT_ROOT
getServletContext().g 網頁文件的根目錄
etRealPath("/")
PATH_INFO
getPathInfo()
PATH_TRANSLATED getPathTranslated()
Servlet 程式的路徑資訊
Servlet 程式的實際路徑資
訊
QUERY_STRING
getQueryString()
URL 網址傳遞的參數資料
REMOTE_ADDR
getRemoteHost()
客戶端的 IP 位址
REMOTE_HOST
getRemoteAddr()
客戶端的主機名稱
REQUEST_METHOD
getMethod()
HTTP 請 求 為 GET 或
POST 等方法
SCRIPT_NAME
getServletPath()
目前執行程式的檔案路徑
SERVER_NAME
getServerName()
伺服器的網域名稱或 IP 位
址
SERVER_PORT
getServerPort()
SERVER_PROTOCOL getProtocol()
HTTP 通訊協定的埠號
HTTP 通訊協定的版本
86
Java 2 程式設計範例教本
SERVER_SOFTWARE getServletContext().g 伺服器軟體和版本
etServerInfo()
5.
Servlet 程式的輸入介面是 HTML 表單欄位,在瀏覽程式的表單欄位
輸入資料後,送回 Web 伺服器交給 Servlet 程式進行處理,在 Servlet 程
式是使用 ServletRequest 介面物件的 getParameter()方法取得欄位輸入的
字串。
使用 URL 網址的參數傳送資料給 Servlet 程式,使用的是 HTTP 請
求的 GET 方法,HTML 的超連結標籤<a>,如下所示:
<a href="servlet\Ch19_4_1?Username=陳會安
&Password=test@ms1.hinet.net"> </a>
上述超連結請求 Servlet 程式 Ch19_4_1,傳遞 2 個參數 Username
和 Password。
POST、GET
6.
請參考第 19-5 節的程式範例
7.
請參考第 19-4-1 節建立新增記錄的 HTML 表單網頁和取得表單欄
位內容的 Servlet 程式
8.
請參考第 19-4-1 節和 19-6 節建立輸入書號的網頁表單和 Java
Servlet 來執行 SQL 指令
9.
請參考第 19-4-1 節和 19-6 節的程式碼
10.
請參考第 15 章、第 19-4-1 節和 19-6 節的程式碼
第 20 章:JSP 動態網頁程式設計
習題解答
1.
「JSP」(JavaServer Pages)是昇陽的伺服端網頁技術,它是 Java
家族中與 ASP 技術一較高下的網頁技術,以 Java 語言來說,Java Applet
是下載到客戶端執行的程式檔,Servlet 是在伺服端執行,JSP 是結合
HTML 和 Java Servlet 的一種伺服端網頁技術。
JSP 和 Java Servlet 技術的主要差異在於 Servlet 是讓程式設計者開
發 Web 伺服器的擴充功能,例如:「JSP 引擎」(JSP Engine)本身就
是一個 Java Servlet,用來擴充 Web 伺服器的功能以便支援 JSP。而 JSP
主要是讓網頁設計者能夠輕鬆建立動態的網頁內容。
JSP 程式的執行過程
JSP 程式碼是內嵌於 HTML 檔案中,當瀏覽程式向 Web 伺服器請
求 JSP 程式時,伺服端支援 JSP 引擎(JSP Engine),或稱為 JSP 容器
(JSP Container)的 Web 伺服器會先將 JSP 程式碼轉換成 Java Servlet,
然後編譯和執行 Servlet 輸出 HTML 標籤,最後產生一份不含 JSP 程式
碼的 HTML 文件,等到傳送到客戶端後,在瀏覽程式顯示的就是這份純
HTML 標籤的網頁內容,如下圖所示:
88
Java 2 程式設計範例教本
上述圖例可以看出 JSP 和 Servlet 擁有密切關係,簡單的說,支援
JSP 的 Web 伺服器會自動將 JSP 轉換成 Servlet 程式碼,以 Resin 伺服器
為 例 , 轉 換 成 的 Servlet 程 式 碼 是 儲 存 在 「 C:\resin-3.0.8\doc\WEBINF\work\_jsp」資料夾。
事實上,執行 JSP 程式回應客戶端瀏覽程式顯示的內容仍是標準
HTML 文件,所以,不論 Netscape 或 Internet Explorer 瀏覽程式都可以
正確顯示網頁內容,換句話說,JSP 是與瀏覽程式無關的網頁技術。
2.
JSP 程式檔案的內容主要分為 HTML 標籤的範本本文和 JSP 元素兩
大部分,如下所示:

範本本文(Template Text):這部分是直接送到客戶端瀏覽程式顯
示的資料,主要是指靜態網頁內容的 HTML 標籤或一般文字內容,
用來作為網頁內容的範本(因為我們是在 HTML 標籤中插入動態顯
示的 JSP 元素)。

JSP 元素(JSP Elements):JSP 元素是 JSP 容器需要處理或轉換成
Servlet 程式碼的部分,可以分為腳本元素(Scripting Elements)、指
引元素(Directive Elements)和動作元素(Action Elements)三種。
3.
在 JSP 程式可以重複使用 JavaBeans 元件和匯入 Java 套件,不只如
此,JSP 還提供一些自動定義的「預設變數」(Predefined Variables),
這是一些物件變數,稱為「隱含物件」(Implicit Objects),如下表所
示:
變數
對應的類別與介面
說明
application
javas.servlet.ServletContext
取得伺服器的系統環境
變數和建立所有使用者
習題解答
的共用資料
session
javax.servlet.http.HttpSession
JSP 的 Session 處理物件
page
java.lang.Object.
這是目前請求和正在處
理的網頁,相當於 Java
語言的 this
pageContext
java.servlet.jsp.PageContext
提供單一 API 介面可以
取得所有隱含物件的屬
性值,也就是目前網頁
的狀態
out
javax.servlet.jsp.JspWriter
輸出串流,輸出到客戶
端瀏覽程式顯示
request
javax.servlet.ServletRequest
取得客戶端請求的相關
資訊,包含參數、方法
Cookie 和 HTTP 標頭資
訊
response
javax.servlet.ServletResponse
回應客戶端請求的狀態
碼、標頭和 Cookie 等
資訊
config
javax.servlet.ServletConfig
JSP 程式轉換成 Servlet
初始資訊的相關參數
exception
request
java.lang.Throwable
JSP 的錯誤處理物件
90
Java 2 程式設計範例教本
4.
請參考第 20-3-2 節的程式範例
5.
請參考第 20-3-1 節的程式範例
6.
請參考第 20-4-1 節建立新增記錄的 HTML 表單網頁和取得表單欄
位內容的 JSP 程式來執行 SQL 指令
7.
請參考第 20-4-1 節和 20-5 節建立輸入書號的網頁表單和 JSP 程式
來執行 SQL 指令
8.
請參考第 20-4-1 節和 20-5 節的程式碼
9.
請參考第 15 章、第 20-4-1 節和 20-5 節的程式碼
10.
請參考第 15 章、第 20-4-1 節和 20-5 節的程式碼
第 21 章:資料結構與 Java
1.
「資料結構」(Data Structures)是一門計算機科學的基礎學科,其
目的是研究程式使用的資料在電腦記憶體的儲存方式,以便撰寫程式處
理問題時,能夠使用最佳的資料結構,並且提供一種策略或方法能夠有
效率的善用這些資料,以便達到下列的目的,如下所示:

程式執行速度快。

資料佔用最少的記憶空間。

更快速的存取這些資料。
習題解答
上述的策略或方法是指如何選擇最恰當的資料結構,並且將這些資
料轉換成有用的資訊,如下圖所示:
上述圖例轉換資料的方法稱為「演算法」(Algorithm)。演算法的
基本定義,如下所示:
演算法是完成目標工作的一組指令,這組指令的步驟是有限的。除此之外,演
算法還必須滿足一些條件,如下所示:
 輸入(Input):沒有或數個外界的輸入資料。
 輸出(Output):至少有一個輸出結果。
 明確性(Definiteness):每一個指令步驟都十分明確,沒有模稜兩可。
 有限性(Finiteness):這組指令一定會結束。
 有效性(Effectiveness):每一個步驟都可行,可以追蹤其結果。
根據上述演算法設計的程式一定會結束,但是並非所有的程式都滿
足這項特性。例如:作業系統,除非系統當機,否則永遠執行一個等待
的迴圈,等待使用者輸入指令。
演算法能夠使用很多種方法來描述這組指令的執行過程,如下所
示:

一般語言文字:直接使用文字描述來說明。

虛擬碼(Pseudo Code):一種趨近程式語言的描述方法,如下所
示:
// 計算 1 加到 10
Let counter = 1;
Let total = 0;
while counter <= 10;
92
Java 2 程式設計範例教本
total = total + counter;
Add 1 to counter;
Output the total; // 顯示結果

流程圖(Flow Chart):使用結構化的圖表描述執行的過程。
事實上,演算法和資料結構的關係非常的密切,因為程式使用的演
算法和資料結構都會影響程式的執行效率,換句話說,演算法加上資料
結構就等於程式。
2.
堆疊的三種操作方法,如下表所示:
方法
說明
boolean isStackEmpty()
檢查堆疊是否已空,傳回值 true 為空,false 為
仍有資料
void push(int)
將參數 int 的資料存入堆疊
int pop()
取出堆疊的資料
堆疊資料結構擁有兩種特性,如下所示:

只允許從堆疊的頂端存取資料。

資料存取的順序是後出先進(Last Out, First In),也就是後存入堆
疊的資料,反而先行取出。
佇列資料結構擁有兩種特性,如下所示:

從佇列的一端存入資料,從另一端讀取資料。
習題解答
資料存取的順序是先進先出(First In, First Out),也就是先存入佇

列的資料,先行取出。
3.
「二元樹」(Binary Tree)屬於樹狀結構的一種特例,樹的「節
點」(Node)最多只有 2 個子節點,其基本定義如下所示:
 二元樹的節點個數是有限,而且可以沒有節點。
 二元樹的樹根下可以分為兩個子樹稱為「左子樹」(Left Subtree)和「右
子樹」(Right Subtree)。
一棵二元樹的範例,如下圖所示:
4.
將節點插在串列的中間位置:假設節點是插在 p 和 q 兩個節點之
間,p 是 q 的前一個節點,如下圖所示:
94
Java 2 程式設計範例教本
只需將 p 指標指向新節點 newnode,然後將新節點指標指向 q,就
可以插入新節點,如下圖所示:
newnode.next=ptr.next;
ptr.next = newnode;
5.
刪除串列的中間節點:將刪除節點前一個節點的 next 指標,指向刪
除節點下一個節點,例如:刪除節點 3,如下圖所示:
在執行刪除節點 3 操作後的串列圖形,如下圖所示:
習題解答
while (current.next != ptr)
current = current.next;
current.next = ptr.next;
6.
陣列堆疊資料結構。
// StackInterface 介面宣告
public interface StackInterface {
// 介面方法: 檢查堆疊是否是空的
boolean isStackEmpty();
// 介面方法: 將資料存入堆疊
boolean push(int d);
// 介面方法: 從堆疊取出資料
int pop();
}
class Stack_Array implements StackInterface {// 堆疊類別
private int[] stack;
// 宣告陣列
private int top;
// 堆疊頂端索引
// 建構子: 建立堆疊
public Stack_Array(int size) { …… }
// 方法: 檢查堆疊是否是空的
public boolean isStackEmpty() { …… }
// 方法: 將資料存入堆疊
public boolean push(int d) { …… }
// 方法: 從堆疊取出資料
public int pop() { …… }
}
7.
儲存 String 物件的二元樹資料結構。
class TreeNode
{ String data;
TreeNode left;
TreeNode right;
public TreeNode(String data)
{ this.data = data;
this.left = null;
this.right = null;
}
}
8.
前序和後序走訪。
public void preOrder(TreeNode ptr) {
96
Java 2 程式設計範例教本
if ( ptr != null ) {
// 終止條件
// 顯示節點內容
System.out.print("[" + ptr.data + "]");
preOrder(ptr.left); // 左子樹
preOrder(ptr.right); // 右子樹
}
}
// 方法: 前序走訪顯示二元樹
public void printPreOrder() {
preOrder(head); // 呼叫前序走訪方法
System.out.println();
}
public void postOrder(TreeNode ptr) {
if ( ptr != null ) {
// 終止條件
postOrder(ptr.left); // 左子樹
postOrder(ptr.right); // 右子樹
// 顯示節點內容
System.out.print("[" + ptr.data + "]");
}
}
// 方法: 後序走訪顯示二元樹
public void printPostOrder() {
postOrder(head); // 呼叫後序走訪方法
System.out.println();
}
9.
字元陣列的泡沫和快速排序法。
static void bubbleSort(char[] data) {
int i,j;
// 變數宣告
int count = data.length;
// 取得陣列尺寸
char temp;
for ( j = count; j > 1; j-- ) { // 第一層迴圈
for ( i = 0; i < j - 1; i++ )// 第二層迴圈
// 比較相鄰的陣列元素
if ( data[i+1] < data[i] ) {
temp = data[i+1];
// 交換陣列元素
data[i+1] = data[i];
data[i] = temp;
}
// 顯示第一層迴圈執行後交換的字串
System.out.print(count-j+1);
習題解答
System.out.println(": " + new String(data));
}
}
10.
字元陣列搜尋的線性和二元搜尋法。
static boolean sequential(char[] data,int len,int k) {
for ( int i = 0; i < len; i++ ) // 搜尋迴圈
// 比較是否是鍵值
if ( data[i] == k ) return true;
return false;
}
第 22 章:Java 與 XML
1.
請參閱第 22-1-1 和 22-1-2 節
2.
一般來說,XML 剖析器分析 XML 文件主要有兩種類型,如下所
示:

樹狀基礎的剖析器(Tree-based Parser):將 XML 文件轉換成樹狀
結構,剖析器需要分析完整份 XML 文件後,才能建立樹狀結構,提
供相關介面物件來存取樹狀結構的節點,例如:DOM(Document
Object Model)。

事件基礎的剖析器(Event-based Parser):XML 文件的處理如同讀
取文字檔案的過程,在讀取內容時觸發一系列事件,應用程式提供
函數處理這些事件,以便存取 XML 內容,例如:SAX(Simple API
for XML)。
3.
JXML DOM 物件模型是將 XML 文件視為一棵樹狀結構,提供節點
的相關屬性和方法取得各元素的內容,或是新增、刪增和修改節點的內
容。
98
Java 2 程式設計範例教本
在 JDK 5.0 版支援 JAXP API 1.3 版支援 XML 建議規格 DOM、
XSLT 和。其剖析和物件模型的相關套件,如下表所示:
套件
說明
javax.xml.parsers
提供與開發廠商無關的通用 API 來使用 DOM 和
SAX 剖析和驗證 XML 文件
javax.xml.transform
提供處理 XSLT 轉換的相關類別
javax.xml.validation
JAXP 1.3 版新增的套件,支援 XML Schema 驗證
XML 文件
org.xml.sax
定義基礎的 SAX API 介面,提供事件剖析 XML
文件的 API
org.xml.sax.helpers
提供一些現成類別,可以幫助程式設計者更容易
使用 SAX API
org.w3c.dom
提供支援 DOM 文件的套件,即 Document 物件
JAXP 在載入 XML 文件後,可以使用 org.w3c.dom 提供的「介面」
(Interface)處理 XML 文件的元素和屬性,將 XML 文件內容視為一個
樹狀結構的節點,其主要的介面物件,如下表所示:
DOM 介面物件
說明
Document
樹狀結構表示整份 XML 文件
Node
節點物件,新增、刪除和修改節點的物件
習題解答
NodeList
節點清單物件,即指定節點子節點的整個樹狀結構
Element
XML 元素物件,也就是元素節點
Text
XML 元素內容物件,也就是內容節點
NamedNodeMap
元素節點的屬性集合
4. removeChild()方法
5.
請參考第 22-3-2 節的程式範例
6. XML 文件 mp3.xml
<mp3>
<model></model>
<name></name>
<company></company>
<price></price>
<memory></memory>
</mp3>
第 23 章:MVC 設計模式與 Swing
1.
「MVC 設計模式」(Model-View-Controller Design Pattern)最早是
在 1979 年由 Trygve Reenskaug 在 Xerox 實驗室研究提出的應用程式架
構。
傳 統 程 式 設 計 的 輸 入 ( Input ) 、 處 理 ( Processing ) 和 輸 出
(Output)問題,對應 MVC 設計模式就是將應用程式分成 Model、
Controller 和 View 三種軟體元件,如下圖所示:
100
Java 2 程式設計範例教本
上述圖例的 Model 代表應用程式的資料,View 是以虛擬方式呈現
Model 資料的外觀,Controller 在收到使用者對 View 的相關操作後,負
責控制應用程式的執行,即控制 Model 和 View 元件的狀態改變。
Model 軟體元件
在 MVC 的 Model 是實作商業邏輯(Business Logic)的物件,商業
邏輯是一種關於如何儲存應用程式資料的邏輯,代表資料、狀態和其規
則。
事實上,Model 之所以命名為「模型」,這是因為它是一組模擬真
實世界的物件集合。而且在軟體系統中,Model 是唯一可以存取持續性
儲存媒體(Persistent Storage)的元件,例如:資料庫。
View 軟體元件
在 MVC 的 View 是實作展示邏輯(Presentation Logic)的物件,
View 是 Model 資料的虛擬外觀,簡單的說,View 是將 Model 的資料轉
換成使用者看到的使用介面。
Controller 軟體元件
習題解答
MVC 的 Controller 是整個應用程式的中心,連結 View 和 Model 來
控制應用程式的執行,Controller 是控制資料處理流程的控制者。
簡單的說,Controller 負責管理使用者與 Model 之間的互動,提供
機制可以更改 Model 的狀態。
2. Model、View、Controller
3.
在 Swing 套件提供的元件是依據 MVC 設計模式所建立的 GUI 元
件,每一種 Swing 元件都可以分為 Model、繪出外觀的 View 和事件處
理的 Controller,如下圖所示:
上述圖例的 Swing 元件分為 Model 物件,至於 View 和 Controller
對於 Swing 元件來說,在實作上很難將進行分割,所以,Swing 元件將
這兩部分合併成 UI 物件(User-interface Object),也稱為「可分割模型
架構」(Separable Model Architecture)。
MVC 與 Swing 元件
Swing 套件的 JButton 元件可以使用 MVC 設計模式分割成 Model,
和結合 View 和 Controller 的 UI 物件,如下所示:
102

Java 2 程式設計範例教本
Model 物件:實作 ButtonModel 介面的物件可以儲存按鈕內部狀態和
行為,提供存取內部狀態、新增/刪除事件傾聽者和產生事件的方
法。

UI 物件:結合 MVC 的 View 和 Controller,這是實作 ButtonUI 介面
的物件,除了在螢幕上繪出按鈕的外觀和傳回座標、尺寸等資訊
外,還可以執行 AWT 事件處理。
MVC 與 Swing 應用程式
MVC 設計模式的 Swing 應用程式,就是一種圖形使用介面的應用
程 式 。 在 實 作 上 , Swing 應 用 程 式 可 以 分 為 Model 、 View 的 表 單
(Forms)和事件處理(Event Handler)的 Controller,如下所示:

Model 物件:Swing 應用程式的資料和商業邏輯,我們可以使用 Java
類別或第 24 章的 JavaBeans 來實作 Model 物件。

GUI 物件:結合 View 和 Controller 的 GUI,包含將 Model 資料呈現
給使用者的表單物件,和 Controller 物件來處理使用者操作的事件處
理。
4. View 和 Controller
5.
Forms Designer 是一套 Swing 應用程式,它是使用 Swing 元件來建立
GUI 圖形使用介面,預設使用 JGoodies 的 FormLayout 版面配置管理
員,可以直接拖拉 Swing 元件來建立 GUI 介面。簡單的說,Forms
Designer 是一種視覺化 GUI 開發工具,可以快速建立 Java 應用程式的
圖形化使用介面。
習題解答
FormLayout 版面配置管理員是由 JGoodies 專案開發和維護,這是
一種開放原始碼和功能強大的版面配置管理員,它是使用格子為基礎的
版面配置管理員,使用類似表格方式的儲存格來插入和編排 Swing 元
件。
在 FormLayout 版面配置管理員的每一欄、列和儲存格都可以指定
尺寸,換句話說,我們並不是指定 Swing 元件尺寸,而是其所在的動態
儲存格,以便在變更表單尺寸時,能自動調整 Swing 元件的顯示尺寸。
6.
請參考第 23-3 節的說明
7.
請參考第 23-3 和 23-4 節的說明來建立表單介面,第 23-5-1 節建立
Swing 應用程式
8.
請參考第 23-6 節的說明
第 24 章:JavaBeans 程式設計
1.
JavaBeans 也稱為 Beans,Beans 的目的是建立軟體元件,以便使用
在「視覺化開發工具」(Visual Builder Tool, VBT),讓開發工具可以
將現成 Bean 元件新增到其他 Java 應用程式,並且直接設定和控制
Beans 元件。
Beans 元件分為圖形 Beans(Graphic Beans)和非圖形 Beans(Nongraphic Beans)。以 MVC 設計模式的 Java 應用程式來說,非圖形
Beans 可以建立 Model 元件所需的商業邏輯處理物件,圖形 Beans 可以
建立使用介面的 View 元件。
104
Java 2 程式設計範例教本
讀者如果曾經使用過微軟 Visual Basic、VB.NET 或 Borland 的
Delphi,就會了解可重複使用元件檔案 VBX 和 OCX 的用途。同理,
Beans 可以新增到 Borland JBuilder 等 Java 的視覺化開發工具,成為可重
複使用的軟體元件,直接在 Java 應用程式新增這些元件,以便「寫一次
Bean 元件,就可以在各地方不同的 Java 應用程式來執行」。
例如:本書第 23 章的 Forms Designer 就是一套視覺化 GUI 介面設
計工具,可以使用 Swing 元件或載入的 JavaBeans 來建立圖形化使用介
面,如下圖所示:
在上述圖例左邊的工具列是支援的可重複元件,其中左下角游標所
在的元件,就是筆者新增名為 Ch24_2_1 的 Bean 元件,在載入 Bean 元
件後,我們可以在 Forms Designer 的表單重複新增此 Beans 元件。
事實上,Java 的每一種 Swing 元件都是依據 JavaBeans 規則所建立
的 Beans 元件,所以在 Forms Designer 工具列支援完整的 Swing 元件,
讓我們直接插入元件來快速建立表單的 GUI 應用程式。
習題解答
2.
「簡單屬性」(Simple Properties)是基本資料型態的實例變數,
「布林屬性」(Boolean Properties)是 boolean 資料型態的實例變數。
「索引屬性」(Indexed Properties)是代表陣列內容的實例變數,換句
話說,這是一組資料的屬性,而不是單一屬性。「邊界屬性」(Bound
Properties)是當 Bean 的屬性變更後,可以自動通知其他物件此事件,
以便其他物件能有所反應。「限制屬性」(Constrained Property)是指
屬性值是在指定的範圍內。當 Bean 元件擁有限制屬性時,外部物件或
元件本身就可以實作 VetoableChangeListener 介面來檢查屬性的限制範
圍。
3.
請參考第 24-2-1 節程式範例
4.
請參考第 24-3-1 節程式範例
5.
請修改 Ch24_5.java 的 vetoableChange()方法來指定限制範圍
6.
請參考第 24-4-2 節程式範例
Download