Java JDK 9學習筆記

qinghuawenkang發表於2018-10-23

北 京
內 容 簡 介
本書是作者多年來教學實踐經驗的總結,彙集了學員在學習 Java 或認證考試時遇到的概念、操
作、應用等問題及解決方案。
本書針對
Java SE 9 新功能全面改版,無論是章節架構或範例程式程式碼,都做了重新編寫與全面
翻新,並詳細介紹了
Java 9 的模組化, JVM JRE Java SE API JDK IDE 之間的對照關係。必
要時可從
Java SE API 的原始碼分析,瞭解各種語法在 Java SE API 中如何應用。對於建議練習的範
例提供了
Lab 文件,以突出練習重點。此外,本書還將 IDE 操作納為教學內容之一,讓讀者能與實
踐相結合,輕鬆快速掌握
Java 程式設計技巧。
本書適合
Java 的初、中級讀者以及廣大 Java 應用開發人員閱讀。
本書資料可透過
免費下載。
北京市版權局著作權合同登記號 圖字: 01-2018-3785
本書封面貼有清華大學出版社防偽標籤,無標籤者不得銷售。
版權所有,侵權必究。侵權舉報電話: 010-62782989 13701121933
圖書在版編目(CIP)資料
Java JDK 9
學習筆記 / 林信良編著 . —北京:清華大學出版社, 2018
ISBN 978-7-302-50118-3
. J … Ⅱ . ①林… Ⅲ . JAVA 語言-程式設計 Ⅳ . TP312.8
中國版本圖書館 CIP 資料核字 (2018) 100148
責任編輯: 王 定
封面設計: 牛豔敏
版式設計: 思創景點
責任校對: 孔祥峰
責任印製: 李紅英
出版發行 :清華大學出版社
網 址
地 址
:北京清華大學學研大廈 A 郵 編 100084
社 總 機
010-62770175 郵 購 010-62786544
投稿與讀者服務
010-62776969 c-service@tup.tsinghua.edu.cn
質 量 反 饋
010-62772015 zhiliang@tup.tsinghua.edu.cn
印 裝 者
:清華大學印刷廠
經 銷 :全國新華書店
開 本 185mm × 260mm 印 張 36.75 字 數 941 千字
版 次 2018 6 月第 1 印 次 2018 6 月第 1 次印刷
定 價 98.00
—————————————————————————————————————————————
產品編號:
079536-01

當你拿起這本書,翻開這篇序,我便有了機會問你一個問題:“為什麼想翻開這本書?”
“這個梗上一版的序用過啦!”
好吧!那學 Java 目的是什麼呢?從事程式設計?那麼我就有個新梗了:“什麼是‘設計’ 呢?”
唔!好難回答的問題,來拜一下 Google 大神吧!搜尋“什麼是設計”,看完答案之後就更不
懂了,在沒有一個具體目標之前,得到的可能都是近乎空洞的答案吧!
試著在身邊找個東西,比如鍵盤,你覺得設計得好嗎?不好?哪裡覺得不好?觸感!什麼樣
的是不好?反饋的力道!反饋是來自哪裡?鍵軸!鍵軸是由哪些成分組成的呢?底座、彈簧、軸
心、軸帽!造成反饋差異性的主要來源是什麼?彈簧和軸心!喔?彈簧啊?它的圈數是多少
呢?……
當你逐一挖掘出其中的元素之後,面對一個覺得設計不錯的鍵盤,或許你就能知道其中有哪
些“設計”了。
很多時候,當談到一件東西設計得好或不好時,並不會明確地知道自己在講什麼,只是綜合
了各種感覺而得到的模糊結論。當然,在平時生活中,並不用每件事物都得探究到底,只是當某
個事物是喜愛的、想賴以維生的,或者是兩者綜合,以為喜歡某個事物,因而想要進一步賴以維
生,這個時候就不能只靠個模糊結論來搪塞下去了。
當你拿起這本書,表示選擇了 Java 這門程式設計語言,為什麼呢?因為 Java 可以寫程式。可
以寫程式的語言很多啊!因為可以寫手機 APP?那為什麼不選 Objective-C 或 Swift 呢?因為聽說
業界很缺?喔!缺的是哪個工作性質的職位?手機……好吧!再問下去,可能有人只是被說服參
加了三個月的 APP 補習課程,只好硬著頭皮繼續學下去了……
Java 本身是門程式設計語言,本身就有設計的成分在裡頭,基於物件導向典範,後來有了一
些函式式典範的影子。 Java 不是門簡潔的語言,然而為了解決這方面問題,近來在語言設計上有
了不少簡化語法,把 Java 用在許多層面, Java 面對了為模組化制訂標準的需求……
然而解決問題並不能只靠程式語言,面對不同的問題,需要設計各種流程,也有不同的資料
結構設計。對於更復雜的問題,得靠更有效率的演算法。當專案有一定規模,有彈性的架構設計是
必要的。為了掌握程式的行為,就得設計可測試的程式;想要避免被入侵,必須將安全上的設計
納入考慮;當龐大的資料迎面而來,平行化方案的設計可能就得出現了……
設計是用來解決問題的!你喜歡或討厭一種設計,代表它在解決問題上是否順你的心、得你
的意,從而認定一個設計是否優雅。

II
既然已經選擇了 Java, 那表示你得接受它的設計了。 那麼接下來的問題, 就在於怎麼使用 Java
來表達你的設計了。不過,這也得真的有能夠表達的設計,你有能表達的演算法設計嗎?資料結構
設計?測試上的設計?架構上的設計?安全上的設計?平行處理的設計?……
過去、現在或未來,你寫的程式中,真的有“設計”的成分在嗎?
林信良
2017 年 12 月
導 讀
這份導讀讓你可以更瞭解如何使用本書。
新舊版差異
就目錄上來說,你可以看出的差異是,上一版為 18個章節,新版為 19 個章節,第 19 章“深
入模組化”是新的章節,也是 JDK9 最重要的新增功能。然而,認識模組化最好的方式是從實際
的例子著手,因此第 1~18章,全部的範例都是採用模組專案構建。而在各章說明時若有需要,也
適時地帶入了常用的模組化概念。第 19 章一開始則是整理前 18 個章節遇到過的模組化介紹,然
後緊接著深入探討模組化。
當然,照例要談一些 JDK9 的其他新增功能,散落在各章節中適當的地方介紹。如果發現頁
側有 圖示,表示提及 JDK9 新功能,本書還提供了 JDK9 新功能快速查詢目錄。
雖然程式常用來處理計算,然而許多開發者對數字處理其實認識不多,因而第 15章通用 API
增加了數字處理的內容;為了認識 JDK9 Stack-Walking API,讀者有必要先認識如何取得並運用
StackTraceElement來進行堆疊追蹤,因而在第 15章還增加了一個小節來介紹堆疊追蹤,對於讀者
瞭解應用程式行為,或者是處理 Bug,應該會有所幫助。
在第 2 章介紹了模組化之後,範例專案便基於模組化設計了,並使用了 JDK9 的語法增強或
改進部分程式程式碼;在 9.1.6節介紹 Lambda 之後,為了提高可讀性,使用 Lambda相關語法或 API
來操作程式範例。
舊版有個附錄 B“視窗程式設計”,在新版中刪掉了,這表示了 Java 在視窗程式這塊的地位。
當然, Java有 Java FX這項技術,如果仍希望使用 Java進行視窗程式設計,可以尋找 Java FX的專
書。附錄 B 雖然不在了,不過範例專案的程式程式碼留著作為第 19 章的練習,讀者可以自行研讀
原始碼,並試著將之模組化。如果一定需要點說明,可以參考舊版《Java SE 6 技術手冊》第 19
章說明:
github.com/JustinSDK/JavaSE6Tutorial/blob/master/docs/CH19.md
字型
本書正文中與程式程式碼相關的文字,都用固定字型來加以呈現,以與一般名詞相區別。例如,
JDK是一般名詞,而
String 則是程式程式碼相關文字,所以使用了固定字型以區分。
IV
程式範例
讀者可以在以下網址下載本書的範例:


本書許多範例都使用完整程式操作來展現,如看到以下程式程式碼示範時:
ClassObject Guess.java
package cc.openhome;
import java.util.Scanner;
import static java.lang.System.out;
public class Guess {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int number = (int) (Math.random() * 10);
int guess;
do {
System.out.print("猜數字(0 ~ 9) :");
guess = scanner.nextInt();
} while(guess != number);
out.println("猜中了...XD");
}
}
範例開始的左邊名稱為 ClassObject 表示可以在範例檔案的 samples 資料夾的各章節資料夾中
找到對應的 ClassObject專案;而右邊名稱為 Guess.java表示可以在專案中找到 Guess.java檔案。如
果程式程式碼中出現標號與提示文字,表示在後續的正文中,會有對應於標號及提示的更詳細說明。
原則上,建議讀者每個專案範例都能親手動作撰寫,但出於教學時間或操作時間上的考慮,
本書有建議進行的練習。如果在範例開始前有個 圖示,例如:
Game1 SwordsMan.java
package cc.openhome;
public class SwordsMan
extends Role {
public void fight() {
System.out.println("揮劍攻擊");
}
}
表示建議範例動手操作,而且在範例檔案的 labs 資料夾中提供了練習專案的基礎,開啟專案
後,完成專案中遺漏或必須補齊的程式程式碼或設定即可。
如果使用以下程式程式碼呈現,則表示它是一個完整的程式內容,而不是專案的一部分,這主
要用來展現一個完整文件的撰寫方法。
Y 建立 Scanner 例項
Z 取得下一個整數
X 告訴編譯程式接下來想偷懶
導 讀
V
public class Hello {
public static void main(String[] args) {
System.out.println("Hello!World!");
}
}
如果使用以下程式程式碼,則表示它是個程式碼段,主要展現程式撰寫時需要特別注意的片段:
SwordsMan swordsMan = new SwordsMan();
...
System.out.printf(" 劍士 (%s, %d, %d)%n", swordsMan.getName(),
swordsMan.getLevel(), swordsMan.getBlood());
Magician magician = new Magician();
...
System.out.printf(" 魔法師 (%s, %d, %d)%n", magician.getName(),
magician.getLevel(), magician.getBlood());
提示框
在本書中會出現以下提示框:
針對課程中所提到的觀點,提供了一些額外的資源或思考方向,暫時忽略這些提示對
課程的影響,但有時間的話,針對這些提示做閱讀、思考或討論是有幫助的。
針對課程中所提到的觀點,以提示框方式特別呈現出必須注意的一些使用方式、陷阱
或避開問題的方法,看到這個提示框時請讀者集中精神閱讀。
附錄
範例檔案包括本書中的所有範例,提供 NetBeans範例專案,附錄 A用於說明如何使用這些範
例專案。
聯絡作者
若有本書勘誤反饋等相關書籍問題,可透過網站與作者聯絡。網址如下:


目 錄
Chapter 1 Java 平臺概論 ·················· 1
1.1 Java 不只是語言························2
1.1.1 前世今生 ································ 2
1.1.2 三大平臺 ································ 5
1.1.3 JCP JSR····························· 6
1.1.4 Oracle JDK OpenJDK ······· 7
1.1.5 建議的學習路徑 ···················· 8
1.2 JVM/JRE/JDK ·························12
1.2.1 什麼是 JVM························· 12
1.2.2 區分 JRE JDK ················· 14
1.2.3 下載、安裝 JDK·················· 15
1.2.4 認識 JDK 安裝內容 ············· 18
1.3 重點複習 ·································19
Chapter 2 從 JDK 到 IDE················· 21
2.1 從 Hello World 開始················22
2.1.1 撰寫 Java 原始碼 ················· 22
2.1.2 PATH 是什麼 ························ 24
2.1.3 JVM( java ) CLASSPATH ···· 27
2.1.4 編譯程式 ( javac )
CLASSPATH ·························· 29
2.2 管理原始碼與位碼文件 ··········30
2.2.1 編譯程式 ( javac )
SOURCEPATH ························ 30
2.2.2 使用 package 管理類 ·········· 32
2.2.3 使用 import 偷懶 ··············· 34
2.3 初識模組平臺系統··················36
2.3.1 JVM( java ) modulepath ··································· 37
2.3.2 編譯程式 ( javac )
module-path ······················ 39
2.3.3 編譯程式 ( javac )
module-source-path ······· 40
2.4 使用 IDE··································41
2.4.1 IDE 專案管理基礎 ·············· 41
2.4.2 使用了哪個 JRE ·················· 47
2.4.3 類文件版本 ························· 49
2.5 重點複習 ·································51
Chapter 3 基礎語法 ·························53
3.1 型別、變數與運算子··············54
3.1.1 型別 ····································· 54
3.1.2 變數 ····································· 57
3.1.3 運算子 ································· 60
3.1.4 型別轉換 ····························· 65
3.2 流程控制 ·································68
3.2.1 if...else 條件式 ·············· 68
3.2.2 switch 條件式 ···················· 70
3.2.3 for 迴圈 ······························ 72
3.2.4 while 迴圈 ·························· 73
3.2.5 break continue ·············· 74
3.3 重點複習 ·································76
3.4 課後練習 ·································77
Chapter 4 認識物件 ·························78
4.1 類與物件 ·································79
4.1.1 定義類 ································· 79
4.1.2 使用標準類 ························· 81
4.1.3 物件指定與相等性 ·············· 84
4.2 基本型別打包器······················86
4.2.1 打包基本型別 ······················ 86
4.2.2 自動裝箱、拆箱 ·················· 87
4.2.3 自動裝箱、拆箱的內幕 ······ 88
4.3 陣列物件 ·································90

VIII
4.3.1 陣列基礎 ······························ 91
4.3.2 運算元組物件 ······················ 93
4.3.3 陣列複製 ······························ 98
4.4 字串物件····························100
4.4.1 字串基礎 ······················· 101
4.4.2 字串特性 ······················· 103
4.4.3 字串編碼 ······················· 107
4.5 查詢 Java API 檔案 ···············108
4.6 重點複習 ·······························113
4.7 課後練習 ·······························114
Chapter 5 物件封裝······················· 116
5.1 何謂封裝 ·······························117
5.1.1 封裝物件初始流程 ··········· 117
5.1.2 封裝物件操作流程 ··········· 119
5.1.3 封裝物件內部資料 ··········· 121
5.2 類語法細節····························123
5.2.1 public 許可權修飾 ············· 123
5.2.2 關於建構函式 ··················· 125
5.2.3 建構函式與方法過載 ······· 126
5.2.4 使用 this ························· 128
5.2.5 static 類成員 ················· 130
5.2.6 不定長度自變數 ··············· 135
5.2.7 內部類 ······························ 136
5.2.8 傳值呼叫 ··························· 138
5.3 重點複習 ·······························140
5.4 課後練習 ·······························141
Chapter 6 繼承與多型 ··················· 142
6.1 何謂繼承 ·······························143
6.1.1 繼承共同行為 ··················· 143
6.1.2 多型與 is-a························ 147
6.1.3 重新定義行為 ··················· 150
6.1.4 抽象方法、抽象類 ··········· 153
6.2 繼承語法細節························154
6.2.1 protected 成員 ··············· 154
6.2.2 重新定義的細節 ··············· 156
6.2.3 再看建構函式 ··················· 157
6.2.4 再看 final 關鍵字 ··········· 159
6.2.5 java.lang.Object ·········· 160
6.2.6 關於垃圾收集 ···················· 165
6.2.7 再看抽象類 ······················· 167
6.3 重點複習 ·······························169
6.4 課後練習 ·······························170
Chapter 7 介面與多型····················171
7.1 何謂介面 ·······························172
7.1.1 介面定義行為 ···················· 172
7.1.2 行為的多型 ······················· 175
7.1.3 解決需求變化 ···················· 178
7.2 介面語法細節························183
7.2.1 介面的預設 ······················· 183
7.2.2 匿名內部類 ······················· 187
7.2.3 使用 enum 列舉常數 ········· 190
7.3 重點複習 ·······························192
7.4 課後練習 ·······························193
Chapter 8 異常處理 ·······················194
8.1 語法與繼承架構····················195
8.1.1 使用 try catch ·············· 195
8.1.2 異常繼承架構 ···················· 197
8.1.3 要抓還是要拋 ···················· 202
8.1.4 貼心還是造成麻煩 ············ 205
8.1.5 認識堆疊追蹤 ···················· 206
8.1.6 關於 assert ······················ 210
8.2 異常與資源管理····················213
8.2.1 使用 finally ···················· 213
8.2.2 自動嘗試關閉資源 ············ 215
8.2.3 java.lang.AutoCloseable
介面 ··································· 217
8.3 重點複習 ·······························221
8.4 課後練習 ·······························222
Chapter 9 Collection 與 Map ····223
9.1 使用
Collection 收集物件 ····224
9.1.1 認識 Collection 架構 ····· 224
9.1.2 具有索引的 List ·············· 225
9.1.3 內容不重複的 Set ············ 228
IX
目 錄
9.1.4
支援佇列操作的 Queue ···· 232
9.1.5 使用泛型 ··························· 234
9.1.6 簡介 Lambda 表示式 ········ 238
9.1.7 Interable
Iterator ························· 240
9.1.8 Comparable
Comparator ····················· 243
9.2 鍵值對應的
Map ·····················248
9.2.1 常用 Map 操作類 ··············· 249
9.2.2 訪問 Map 鍵值 ··················· 252
9.3 不可變的
Collection
Map ·········································· 255
9.3.1 淺談不可變特性 ··············· 255
9.3.2 Collection s
unmodifiableXXX()
方法 ·································· 256
9.3.3 List Set Map of()
方法 ·································· 258
9.4 重點複習 ·······························260
9.5 課後練習 ·······························262
Chapter 10 輸入/輸出···················· 263
10.1
InputStream
OutputStream ··························264
10.1.1 串流設計的概念 ············· 264
10.1.2 串流繼承架構 ················· 266
10.1.3 串流處理裝飾器 ············· 269
10.2 字元處理類····························273
10.2.1 Reader Writer 繼承
架構
································ 274
10.2.2 字元處理裝飾器 ············· 275
10.3 重點複習································277
10.4 課後練習································278
Chapter 11 執行緒與並行 API··········· 279
11.1 執行緒········································280
11.1.1 執行緒簡介 ························· 280
11.1.2 Thread Runnable ······ 282
11.1.3 執行緒生命週期 ················· 284
11.1.4 關於 ThreadGroup ·········· 290
11.1.5 synchronized
volatile ························ 292
11.1.6 等待與通知 ······················ 301
11.2 並行 API ································305
11.2.1 Lock ReadWriteLock
Condition ······················ 305
11.2.2 使用 Executor ················ 313
11.2.3 並行 Collection 簡介 ··· 323
11.3 重點複習································326
11.4 課後練習································327
Chapter 12 Lambda·······················328
12.1 認識 Lambda 語法 ·················329
12.1.1 Lambda 語法概覽 ············ 329
12.1.2 Lambda 表示式與函式
介面
································· 332
12.1.3 Lambda 上 this
final ······························· 334
12.1.4 方法與建構函式參考 ······ 336
12.1.5 介面預設方法 ·················· 338
12.2 Functional 與 Stream API·······343
12.2.1 使用 Optional 取代
null ································· 343
12.2.2 標準 API 的函式介面 ······ 345
12.2.3 使用 Stream 進行管道
操作
································· 348
12.2.4 進行 Stream reduce
collect ······················ 351
12.2.5 關於 flatMap() 方法 ······ 356
12.2.6 Stream 相關 API ············· 359
12.2.7 JDK9 Optional
Stream 增強 ···················· 360
12.3 Lambda、平行化與非同步
處理········································362
12.3.1 Stream 與平行化 ············ 362
12.3.2 Arrays 與平行化 ············ 366
X
12.3.3 CompletableFuture
非同步處理 ····················· 367
12.3.4 JDK9 CompletableFuture
增強 ································ 369
12.4 重點複習································370
12.5 課後練習································371
Chapter 13 時間與日期 ················· 372
13.1 認識時間與日期 ····················373
13.1.1 時間的度量 ····················· 373
13.1.2 年曆簡介 ························· 374
13.1.3 認識時區 ························· 375
13.2 認識
Date Calendar ············376
13.2.1 時間軸上瞬間的 Date ···· 376
13.2.2 格式化時間日期的
DateFormat ···················· 377
13.2.3 處理時間日期的
Calendar ························ 379
13.2.4 設定 TimeZone ··············· 382
13.3 新時間日期 API·····················383
13.3.1 機器時間觀點的 API ······ 383
13.3.2 人類時間觀點的 API ······ 385
13.3.3 對時間的運算 ················· 387
13.3.4 年曆系統設計 ················· 389
13.4 重點複習································390
13.5 課後練習································391
Chapter 14 NIO 與 NIO2··············· 393
14.1 認識 NIO································394
14.1.1 NIO 概述 ························· 394
14.1.2 Channel 架構與操作 ······ 395
14.1.3 Buffer 架構與操作 ········ 396
14.2 NIO2 檔案系統······················398
14.2.1 NIO2 架構 ······················· 398
14.2.2 操作路徑 ························· 399
14.2.3 屬性讀取與設定 ············· 401
14.2.4 操作文件與目錄 ············· 404
14.2.5 讀取、訪問目錄 ············· 406
14.2.6 過濾、搜尋文件 ············· 410
14.3 重點複習································412
14.4 課後練習································413
Chapter 15 通用 API······················414
15.1 日誌········································415
15.1.1 日誌 API 簡介 ·················· 415
15.1.2 指定日誌層級 ·················· 417
15.1.3 使用 Handle r
Formatter ······················ 419
15.1.4 自定義 Handler Formatter
Filter ························ 420
15.1.5 使用 logging.
properties
···················· 422
15.2 國際化基礎····························423
15.2.1 使用 ResourceBundle ···· 423
15.2.2 使用 Locale ···················· 424
15.3 規則表示式····························426
15.3.1 規則表示式簡介 ·············· 426
15.3.2 Pattern Matcher ······· 433
15.4 處理數字································435
15.4.1 使用 BigInteger ············ 435
15.4.2 使用 BigDecimal ············ 437
15.4.3 數字的格式化 ·················· 439
15.5 再談堆疊追蹤························441
15.5.1 獲取
StackTraceElement ······· 441
15.5.2 JDK9 StackWalking API ···················· 443
15.6 重點複習································447
15.7 課後練習································448
Chapter 16 整合資料庫··················449
16.1 JDBC 入門 ·····························450
16.1.1 JDBC 簡介 ······················· 450
16.1.2 連線資料庫 ······················ 454
16.1.3 使用 Statement
ResultSet ······················ 459
16.1.4 使用 PreparedStatement
CallableStatement ······ 464
XI
目 錄
16.2 JDBC 進階 ·····························468
16.2.1 使用 DataSource 取得
聯機
································ 468
16.2.2 使用 ResultSet 捲動、
更新資料
························· 471
16.2.3 批次更新 ························· 473
16.2.4 Blob Clob ·················· 474
16.2.5 交易簡介 ························· 474
16.2.6 metadata 簡介 ··············· 481
16.2.7 RowSet 簡介 ···················· 484
16.3 重點複習································486
16.4 課後練習································487
Chapter 17 反射與類載入器·········· 489
17.1 運用反射································490
17.1.1 Class .class 文件 ········ 490
17.1.2 使用 Class.
forName()
······················ 492
17.1.3 Class 獲得資訊 ········· 494
17.1.4 Class 建立物件 ········· 496
17.1.5 操作物件方法與成員 ······ 499
17.1.6 動態代理 ························· 501
17.1.7 當反射遇上模組 ············· 505
17.1.8 使用 ServiceLoader ····· 511
17.2 瞭解類載入器 ························513
17.2.1 JDK9 類載入器層級 ······· 513
17.2.2 建立 ClassLoader
例項 ································· 516
17.3 重點複習································517
17.4 課後練習································519
Chapter 18 自定義泛型、列舉與
註釋 ···························· 520
18.1 自定義泛型····························521
18.1.1 使用 extends ? ··········· 521
18.1.2 使用 super ? ··············· 525
18.2 自定義列舉····························528
18.2.1 瞭解 java.lang.
Enum
·························· 528
18.2.2 enum 高階運用 ················· 531
18.3 關於註釋································536
18.3.1 常用標準註釋 ·················· 536
18.3.2 自定義註釋型別 ·············· 540
18.3.3 執行時期讀取註釋資訊 ·· 545
18.4 重點複習································548
18.5 課後練習································549
Chapter 19 深入模組化··················550
19.1 運用模組································551
19.1.1 模組的種類 ······················ 551
19.1.2 requires exports
opens 細節 ······················ 554
19.1.3 修補模組 ·························· 557
19.1.4 放寬模組封裝與依賴 ······ 558
19.2 模組 API ································560
19.2.1 使用 Module ···················· 560
19.2.2 使用
ModuleDescriptor ········ 562
19.2.3 淺談 ModuleLayer ·········· 562
19.3 打包模組································564
19.3.1 使用 jar 打包 ·················· 564
19.3.2 使用 jmod 打包 ················ 566
19.3.3 使用 jlink 建立執行時期
映像
································· 568
19.4 重點複習································569
19.5 課後練習································570
Appendix··········································571
A.1 專案環境配置 ·························572
A.2 開啟案例·································572


Java SE 9 新功能索引
Java SE 9後的特性版本時間軸變動································································································ 15
JDK 9 文件實體佈局變動·················································································································· 18
初探模組平臺系統 ····························································································································· 36
javac 新增 -release 引數··················································································································· 50
支援 Unicode 8.0·································································································································· 54
內建 jshell············································································································································· 56
Java API檔案支援搜尋功能············································································································ 112
StackTraceElement 新增方法·········································································································· 207
Try-with-resources 語法改進 ············································································································ 217
定義匿名類別時的泛型語法改進 ·································································································· 239
List Set Map 新增 of( ) 方法 ···································································································· 258
介面支援定義
private 方法 ··········································································································· 340
Collectors 新增 filtering( ) 方法 ······························································································· 356
Collectors 新增 flatMapping( ) 方法 ··························································································· 359
Optional Stream 增強·················································································································· 360
CompletableFuture 增強 ·················································································································· 369
支援 UTF-8編碼的.properities 檔案································································································ 425
Stack-Walking API ····························································································································· 443
反射與類載入器機制······················································································································· 490
@Deprecated 增強······························································································································ 537
ElementType 新增 MODULE ················································································································· 545
深入模組化········································································································································ 551


學習目標
Java 版本遷移簡介
認識 Java SE、 Java EE、 Java ME
認識 JDK 規範與操作
瞭解 JVM、 JRE 與 JDK
下載與安裝 JDK
Java 平臺概論 1
1.1 Java 不只是語言
從 1995 年至今, Java 已經過了 20 多個年頭,經過這些年的改進,正如本節標題所示, Java
已不僅是個程式語言,也代表瞭解決問題的平臺(Platform),更代表了原廠、各個廠商、社群、
開發者與使用者溝通的成果。若僅以程式語言的角度來看待 Java,正如冰山一角,你僅看到 Java
身為程式語言的一部分,而沒看到 Java 身為程式語言之外,更可貴也更為龐大的資源。
1.1.1 前世今生
一個語言的誕生有其目的,因為這個目的而成就了該語言的主要特性。探索 Java 的歷史演
變,對於掌握 Java 特性與各種可用資源,有很大幫助。
1. Java 誕生
Java 最早是 Sun 公司綠色專案(Green Project)中撰寫 Star7 應用程式的程式語言,當時的名
稱並不是 Java,而是 Oak。
綠色專案始於 1990 年 12 月,由 Patrick Naughton、 Mike Sheridan 與 James Gosling(James
Gosling 被尊稱為 Java 之父)主持,目的是希望構築出下一波計算機應用趨勢並加以掌握,他們
認為下一波計算機應用趨勢會集中在消費性數字產品(就像現在的 PDA、手機等消費性電子商
品)的使用上。 1992 年 9 月 3 日, Green Team 專案小組展示了 Star7 手持裝置,這個裝置具備無
線網路連線、 5 寸 LCD 彩色螢幕、 PCMCIA 介面等功能,而 Oak 在綠色專案中的目的,是用來
撰寫 Star7 上應用程式的程式語言。
Oak 名稱的由來,是因為 James Gosling 的辦公室窗外有一棵橡樹(Oak),就取了這個名稱。
但後來發現 Oak 已經被註冊了,工程師們邊喝咖啡邊討論著新名稱,最後靈機一動而改名為
Java。
Java 本身有許多為了節省資源而作的設計,如動態載入類別文件、字串池(String Pool)
等特性,這是因為 Java 一開始就是為了消費性數字產品而設計,而這類小型裝置通常有著有限
記憶體與運算資源。
全球資訊網(World Wide Web)興起, Java Applet 成為網頁互動技術的代表。
1993 年第一個全球資訊網瀏覽器 Mosaic 誕生, James Gosling 認為網際網路與 Java 的一些特
性不謀而合,利用 Java Applet 在瀏覽器上展現互動性媒體,在當時而言,對視覺感官是一種
革命性的顛覆。 Green Team 仿照 Mosaic 開發出以 Java 技術為基礎的瀏覽器 WebRunner(原名
為 BladeRunner),後來改名為 HotJava。雖然 HotJava只是一個展示性產品,但它使用 Java Applet
展現的多媒體效果立即吸引了許多人的注意,圖 1.1 所示即為 JDK 所附的 Java Applet 範例。
1995 年 5 月 23 日(這一天被公認為 Java 的誕生日),正式將 Oak 改名為 Java, Java
Development Kits(當時 JDK 的全名)1.0a2 版本正式對外發表。 到 1996 年, Netscape Navigator 2.0
也正式支援 Java, Microsoft Internet Explorer 也開始支援 Java。從此, Java 在網際網路的世界中逐
漸風行起來。雖然 Star7 產品並不被當時消費性市場接受,綠色專案面臨被裁撤的命運,然而
全球資訊網的興起卻給了 Java 新的生命與舞臺。


2. 版本演進
隨著 Java 越來越受到矚目, Sun 在 1998 年 12 月 4 日釋出 Java 2 Platform,簡稱 J2SE 1.2。
Java 開發者版本一開始是以 Java Development Kit 名稱發表,簡稱 JDK,而 J2SE 則是平臺名
稱,包含了 JDK 與 Java 程式語言。
Java 平臺標準版約以兩年為週期推出重大版本更新, 1998 年 12 月 4 日發表 J2SE 1.2,
2000 年 5 月 8 日發表 J2SE 1.3, 2002 年 2 月 13 日發表 J2SE 1.4, Java 2 這個名稱也從 J2SE 1.2
開始沿用至各個版本。
2004 年 9 月 29 日發表的 Java 平臺標準版的版號不是 1.5,而直接跳到 5.0,稱為 J2SE 5.0,
這是為了彰顯這個版本與之前版本有極大不同,如語法上的簡化、增加泛型(Generics)、列舉
(Enum)、註釋(Annotation)等重大功能。
2006 年 12 月 11 日發表的 Java 平臺標準版,除了版本號之外,名稱也有了變化,稱為 Java
Platform, Standard Edition 6,簡稱 Java SE 6。 JDK6 全名則稱為 Java SE Development Kit
6,也就是不再像以前 Java 2 帶有 2 這個號碼,版本號 6 或 1.6.0 都使用, 6 是產品版本(Product
Version),而 1.6.0 是開發者版本(Developer Version)。
大部分的 Java 標準版平臺都會取個程式碼名稱(Code Name),例如 J2SE 5.0 的程式碼名稱為
Tiger(老虎),為了引人注目,在發表會上還真的抱了一隻小白老虎出來作為噱頭,而許多書的
封面也相應地放上老虎的圖片。有關 JDK 程式碼名稱與釋出日期,如表 1.1 所示。
表 1.1 Java 版本、程式碼名稱與釋出日期

版 本 代 碼 名 稱 發 布 日 期
JDK 1.1.4 Sparkler(煙火) 1997/9/12
JDK 1.1.5 Pumpkin(南瓜) 1997/12/3
JDK 1.1.6 Abigail(聖經故事人物名稱) 1998/4/24
JDK 1.1.7 Brutus(羅馬政治家名稱) 1998/9/28
JDK 1.1.8 Chelsea(足球俱樂部名稱) 1999/4/8
J2SE 1.2 Playground( 遊樂場 ) 1998/12/4
J2SE 1.2.1 1999/3/30
J2SE 1.2.2 Cricket(蟋蟀) 1999/7/8
J2SE 1.3 Kestrel( 紅隼 ) 2000/5/8


( 續表 )

版 本 代 碼 名 稱 發 布 日 期
J2SE 1.3.1 Ladybird(瓢蟲) 2001/5/17
J2SE 1.4.0 Merlin( 魔法師名稱 ) 2002/2/13
J2SE 1.4.1 Hopper(蚱蜢) 2002/9/16
J2SE 1.4.2 Mantis(螳螂) 2003/6/26
J2SE 5.0 Tiger( 老虎 ) 2004/9/29
Java SE 6 Mustang( 野馬 ) 2006/12/11
Java SE 7 Dolphin( 海豚 ) 2011/7/28
Java SE 8 2014/3/18
Java SE 9 2017/9/21


撰寫本書時,表 1.1 參考的資料來源網址如下 ( 其中列出至 J2SE 5.0)

3. 江山易主
之前談過, Java 約以兩年為週期推出重大版本更新,正如表 1.1 所示, J2SE 1.2、 J2SE 1.3、
J2SE 1.4.0、 J2SE 5.0、 Java SE 6 推出的時間間隔,差不多都是兩年。然而從 Java SE 6 之後,
Java 開發人員足足等了四年多,才等到新版本的推出,不禁讓人想問: Java 怎麼了?
原因有許多, Java SE 7 對新版本的規劃搖擺不定,涵蓋許多不易實現的新特性,加上 Sun
一直營收低迷不振,影響了新版本的推動。新版本推出日期承諾不斷推遲,從 2009 年推遲至
2010 年初,又突然宣佈將加入原本不願劃入 Java SE 7 的 Closure 語法,並將推出日期推遲至
2010 年底。 2010 年年中傳出 IBM 與 Sun 密談併購失敗,沒隔幾日,即爆出 Oracle 宣佈併購
Sun, Java 也正式成為 Oracle 所屬。
併購會帶來一連串的組織重整,導致 Java SE 7 推出日期再度推遲,為了對停滯不前的 Java
注入活水,決定先將現有已實現或較易實現的特性放入 Java SE 7 中,將未定方案或較難實現的
特性放入 Java SE 8 中(比如 Lambda), 2010 年底 JCP(Java Community Process,稍後即會說明這
個組織是什麼)終於透過了 Java SE 7 與 Java SE 8 的規劃地圖(Roadmap),並預定於 2011 年 7 月
左右推出 Java SE 7,這次總算沒有推遲, Java SE 7 正式於 2011 年 7 月 28 日釋出。
Java SE 8 實際上也是一波三折,原定應於 2013 年釋出,卻因為接二連三爆出的 Java 安全
漏洞,迫使 Java 開發團隊決定先行檢查修補 Java 安全問題,幾經延後,最後確定釋出 Java SE 8
的時間為 2014 年 3 月 18 日。
實際上,當初為了及早推出 Java SE 7,被推遲至 Java SE 8 的重大特性還有 Jigsaw,也就
是 Java 模組平臺系統(Java Platform Module System)。然而當時為了修補 Java 安全問題已經使得
Java SE 8 多次延遲,為了能如期推出 Java SE 8, Java 模組平臺系統並沒有在 Java SE 8 中實現,
而被放到了 Java SE 9 中併成為重大特性之一。雖然如此,推出過程中又因為開發不及,以及發
生了 JCP 執行委員會(JCP Executive Committee)曾經投票否決了 Java 模組平臺系統等因素,使
得 Java SE 9 釋出日期多次推後,終於在 2017 年 9 月 21 日正式釋出。
可以在下面的頁面中,看到 Java 模組平臺系統一度被否決的投票結果:

1.1.2 三大平臺
在 Java 發展的過程中, 由於其應用領域越來越廣, 並逐漸擴充套件至各級應用軟體的開發, Sun
公司在 1999 年 6 月美國舊金山舉辦的 Java One 大會上,公佈了新的 Java 體系架構。該架構根
據不同級別的應用開發區分了不同的應用版本: J2SE(Java 2 Platform, Standard Edition)、
J2EE(Java 2 Platform, Enterprise Edition)與 J2ME(Java 2 Platform, Micro Edition)。
J2SE、 J2EE 與 J2ME 是當時的名稱,由於 Java SE 6 後 Java 不再帶有 2 這個號碼, J2SE、
J2EE 與 J2ME 分別被正名為 Java SE、 Java EE 與 Java ME。
儘管 Sun 2006 年底,就將三大平臺正名為 Java SE Java ME Java EE ,但時至今日,
許多人的習慣並沒有改過來,
J2SE J2ME J2EE 這些名詞還是有很多人用。
1. Java SE
Java 是各應用平臺的基礎,想要學習其他的平臺應用,必先了解 Java SE 以奠定基礎,而
Java SE 也正是本書主要的介紹物件。
圖 1.2 所示是整個 Java SE 的組成概念圖。

圖 1.2 Java SE 的組成概念圖
Java SE 可以分為四個主要的部分: JVM、 JRE、 JDK 與 Java 語言。
為了能夠執行 Java 撰寫好的程式,必須有 Java 虛擬機器(Java Virtual Machine, JVM)。 JVM
包括在 Java 執行環境(Java SE Runtime Environment, JRE)中,所以要執行 Java 程式,必須
先安裝 JRE。 如果要開發 Java 程式, 必須取得 JDK(Java SE Development Kits), JDK 包括 JRE
及開發過程中需要的一些工具程式,如 javac、 java 等工具程式(關於 JRE 及 JDK 的安裝與使用
方法,會在第 2 章說明)。
Java 語言只是 Java SE 的一部分,除此以外,Java 最重要的就是提供龐大且強大的標準 API,
提供字串處理、資料輸入/輸出、網路套件、使用者視窗介面等功能,可以使用這些 API 作為基
礎來進行程式開發,無須重複開發功能相同的元件。事實上,在熟悉 Java 語言之後,更多的時
候,都是在學習如何使用 Java SE 提供的 API 來完成應用程式。
2. Java EE
Java EE 以 Java SE 為基礎,定義了一系列的服務、 API、協議等,適用於開發分散式、多
層次(Multi-tiered)、以元件為基礎、以 Web 為基礎的應用程式。整個 Java EE 的體系是相當龐
大的,比較為人熟悉的技術是 JSP、 Servlet、 JavaMail、 Enterprise JavaBeans(EJB)等,其中每個
服務或技術都可以使用專書進行說明,並非本書說明的範圍。但可以肯定的是,必須在 Java SE
上奠定良好的基礎,再來學習 Java EE 的開發。
3. Java ME
Java ME 是 Java 平臺版本中最小的應用程式,目的是作為小型數字裝置上開發及部署應用
程式的平臺,如消費性電子產品或嵌入式系統等,其中最為人熟悉的裝置如手機、 PDA、股票
機等。可以使用 Java ME 來開發出這些裝置上的應用程式,如 Java 遊戲、股票相關程式、記事
程式、日曆程式等。
1.1.3 JCP 與 JSR
Java 不僅是程式語言,還是標準規範。
先來看看沒有標準會產生什麼問題?我們的身邊有些東西沒有標準,例如手機充電器,不
同廠商的手機,充電器也不相同,家裡面一堆充電器互不相容,換個手機,充電器就不能用的
情況,相信你我都有過。
有標準的好處是什麼?現在許多計算機外部裝置,都採用 USB 作為傳輸介面,這讓計算機
中不用再接上一些轉接器,跟過去計算機主機後面一堆不同規格的傳輸介面相比,實在方便了
不少,現在許多手機的充電器,也改採用 USB 介面了,這真是件好事。
回頭來談談 Java 是標準規範這件事。 你知道嗎?編譯/執行 Java 的 JDK/JRE, 並不只有 Sun
才能實現, IBM 也可以撰寫自己的 JDK/JRE,其他廠商或組織也可以撰寫自己的 JDK/JRE,你
寫的 Java 程式,可以執行在這些不同廠商或組織寫出來的 JRE 上。第 2 章將學到的第一個 Java
程式,其中會有這麼一段程式程式碼:
System.out.println("Hello World");
這行程式目的是:請系統(System)的輸出裝置(out)顯示一行(println)Hello World。是誰決定
使用 System、 out、 println 這些名稱的?為什麼不是 Platform、 Output、 ShowLine 這些名稱?
如果 Sun 使用 System、 out、 println 這些名稱,而 IBM 使用了 Platform、 Output、 ShowLine 這
些名稱, 用 Sun 的 JDK 寫的程式, 就不能執行在 IBM 的 JRE 上, 那 Java 最基本的特性之一“跨
平臺”,就根本無法實現了。
Java 由 Sun 創造,為了讓對 Java 感興趣的廠商、組織、開發者與使用者參與定義 Java 未來
的功能與特性, Sun 公司於 1998 年組成了 JCP(Java Community Process),這是一個開放性國
際組織,目的是讓 Java 的演進由 Sun 非正式地主導,成為全世界數以百計代表成員公開監督
的過程。
任何想要提議加入 Java 的功能或特性,必須以 JSR(Java Specification Requests)正式文
件的方式提交, JSR 必須經過 JCP 執行委員會(Executive Committee)投票透過,方可成為最
終標準檔案,有興趣的廠商或組織可以根據 JSR 實現產品。
若 JSR 成為最終檔案後,必須根據 JSR 做出免費且開發原始碼的參考實現,稱為 RI(Reference
Implementation),並提供 TCK(Technology Compatibility Kit)作為技術相容測試工具箱,方
便其他想根據 JSR 實現產品的廠商或組織參考與測試相容性。 JCP、 JSR、 RI 與 TCK 的關係,
如圖 1.3 所示。

Java 平臺概論 1

圖 1.3 JCP、 JSR、 RI 與 TCK
JCP 官方網站為
現在無論 Java SE、 Java EE 還是 Java ME,都是業界共同制定的標準,每個標準背後都隱
藏著業界所面臨的一些問題,他們期待使用 Java 來解決問題,認為應該有某些元件、特性、應
用程式程式設計介面等,來解決這些問題,因而制定 JSR 作為正式標準規範檔案,不同的技術解決
方案標準規範會給予一個編號。
在 JSR 規範的標準之下,各廠商可以各自操作成品,所以同一份 JSR,可以有不同廠商的
操作產品。以 Java SE 為例,對於身為開發人員,或使用 Java 開發產品的公司而言,只要使用
相容於標準的 JDK/JRE 開發產品,就可以執行、相容在標準的 JRE 上,而不用擔心跨平臺的
問題。
Java SE 9 的主要規範是在 JSR 379 檔案之中,而 Java SE 9 平臺中的特定技術,則規範於特
定的 JSR 檔案之中。若有讀者對這些檔案有興趣,可以參考 JSR379,網址如下:
/en/jsr/detail?id=379
想要查詢 JSR 檔案,只要在 /en/jsr/detail?id= 之後加上檔案編號就可以了,
例如上面查詢
JSR 379 檔案網址就是:
/en/jsr/detail?id=379
JSR
對於 Java 初學者而言過於生澀,但 JSR 檔案規範了相關技術應用的功能,將來有能
力時,可以試著自行閱讀
JSR ,這有助於瞭解相關技術規範的更多細節。
1.1.4 Oracle JDK 與 OpenJDK
在過去, Sun JDK 實現,也就是被 Oracle 收購之後的 Oracle JDK 實現,就是 JDK 的參考
實現,有興趣的廠商或組織也可以根據 JSR 自行實現產品,例如 IBM 就是根據 JSR 實現了自
家的 IBM JDK。 只有透過 TCK 相容性測試的實現,才可以使用 Java 這個商標。
IBM JDK http://www.ibm.com/developerworks/java/jdk/
2006 年的 JavaOne 大會上, Sun 宣告對 Java 開放原始碼,從 JDK7 b10 開始有了
OpenJDK,並於 2009 年 4 月 15 日正式釋出 OpenJDK。 Oracle 時代釋出的 JDK7 正式版本,
指定了 OpenJDK7 為官方參考實現。
1. Oracle JDK7
OpenJDK7
與同為開放原始碼的 Sun JDK 不同的是,Sun JDK 採用 JRL,而 OpenJDK7 採用 GPL(帶

有GPL linking exception 的修正版本),前者原始碼可用於個人研究使用,但禁止任何商業
用途,後者則允許商業使用。因此, OpenJDK7 必須刪掉許多在兩個授權間有衝突的程式程式碼,
也不包括一些部署(Deployment)工具(例如 Java Web Start 等)以及軟體套件(例如 Java DB)等;現
在你在 Java Platform, Standard Edition 7 Reference Implementations(或 Java Platform, Standard
Edition 9 Reference Implementations)下載 RI 時,也會看到有基於 GNU General Public License
version 2 與 Oracle Binary Code License 兩個授權的版本。
Java Platform, Standard Edition 7 Reference Implementations

Java Platform, Standard Edition 9 Reference Implementations


由於 OpenJDK7 中有許多程式程式碼因授權衝突而必須刪掉,因此原始的 OpenJDK7 是不完
整的,所以無法透過 TCK 相容測試。 如果執行
java -version ,原始的 OpenJDK7 顯示的會
是 openjdk version 字樣,而不是 java version 字樣。
為了解決授權問題, 以便在 Fedora 或 Linux 分支中能自由釋出 OpenJDK7, Red Hat 於 2007
年發起了 IcedTea 計劃。而由於原始的 OpenJDK7 是不完整的,後來 IcedTea 致力於修補
OpenJDK7 使之完備,並透過了 TCK 相容測試。 如果使用 IcedTea 修補過後的 OpenJDK7,
執行
java -version ,就會顯示 java version 字樣。
2. OpenJDK7
OpenJDK6
在 OpenJDK 官方網站,也可以看到 OpenJDK6 的版本, OpenJDK6 並不是 Sun JDK6 的
分支,而是將 OpenJDK7 中 JDK7 的特性刪掉,使之符合 JDK6 的規範,因而 OpenJDK6 實際
上是 OpenJDK7 的分支, OpenJDK6 可以透過 TCK 相容測試。
Oracle 從 2012 年 7 月以來,就打算結束對 JDK6 的支援,在 2013 年 2 月時釋出 JDK6 Update
43 時,宣佈這是最後一個免費更新版本(實際上後來還有 Update 45),希望大家趕快升級至
JDK7。
由於 JDK6 在企業間仍廣泛應用, Red Hat 於 2013 年 3 月宣佈持有 OpenJDK6 領導權,
以便能持續對 OpenJDK6 發現的漏洞與安全問題進行修補。
1.1.5 建議的學習路徑
Java 不僅是程式語言,還是標準規範。每個標準代表著廠商面臨的問題,代表著解決問題
的方案,因此,學習 Java 就等於在面臨各式問題如何解決。然而,這麼多的問題衍生出如此多
的解決方案,對於初學 Java 的人而言,如同面臨滿載產品的龐大貨輪,不知從何開始,也不知
將來何去何從。
如果將程式語言比喻為一艘船,會是如何呢?這裡有篇有趣的文章:
http://compsci.ca/blog/if-a-programming-language-was-a-boat/
Java 的官方網站提供了一份 Java 技術概念地圖(Java Technology Concept Map)的檔案, 如圖
1.4 所示。這是份 PDF 檔案,可以在以下網址下載:

圖 1.4 Java 技術概念地圖
Oracle 合併 Sun 之後, Java 的官方網站是:

連線網路之後,將會被重新連結至:

在這份檔案中,密密麻麻地列出了大部分 Java 相關地圖與簡要說明,也代表了 Java 技術
範疇的廣泛。然而要從這麼龐大的地圖中找出一條適合初學 Java 的路線圖絕非易事。以下是我
基於經驗與教學建議的學習路徑。
1. 深入瞭解 JVM/JRE/JDK
許多書籍對於 JVM/JRE/JDK 的說明,通常只用了極短的篇幅介紹,就是在短短几頁中,
請使用者按書中步驟安裝與設定
PATH CLASSPATH 後,就開始介紹 Java 程式語言。而許多人到
了業界後就開始使用 IDE(Integrated Development Environment)代勞所有 JDK 細節。這麼做的結
果就是,在 IDE 中遇到與 JDK 相關的問題,就完全不知道如何解決。
JVM/JRE/JDK 並不是用短短几頁就可以說明,若沒有“JVM 是 Java 程式唯一認識的操作
系統,其可執行檔案為.class 文件”的重要觀念,就無法理解
PATH CLASSPATH 並非同一層級
的 環 境 變 量 , JDK 中 許 多 指 令 與 選 項 其 實 都 可 以 對 應 至 IDE 中 某 個 設 定 與 操 作 。 對
JVM/JRE/JDK 有了足夠的認識,對 IDE 中相關選項就不會有疑問,也不會換個 IDE 就不知所
措,或沒有 IDE 就無法撰寫程式。
2.
理解 封裝、繼承、多型
對於 Java 程式語言,
if...else for while switch 等流程語法早已是必須熟練的基礎。
更重要的是, Java 支援物件導向(Object Oriented),你必須理解物件導向中最重要的封裝
(Encapsulation)、 繼承(Inheritance)、 多型(Polymorphism)概念,以及如何用 Java 相關語法來
實現。
許多人撰寫 Java 程式,並沒有善用其支援物件導向的特性,問到何謂封裝卻無法回答(甚
至回答定義類即為封裝),濫用 Java 繼承語法,不懂多型而不知如何運用 API 檔案,更別說運
用多型設計程式了,最後的結果就是淪於死背 API 檔案、使用“複製、貼上”大法來撰寫程式,
整個應用程式架構雜亂無章且難以維護。
3. 掌握常用 Java SE API 架構
Java 並非只是程式語言,還帶有龐大的各式連結庫(Library),對初學者而言,首要是掌握
常用的 Java SE API, 例如異常(Exception)、集合(Collection)、輸入/輸出串流(Stream)、執行緒(Thread)
等。學習這些標準 API,應先掌握 API 在設計時的封裝、 繼承、 多型架構。 以
Collection
為例,在學習時必須先理解為何要設計如圖 1.5 所示的架構。
產生

圖 1.5 Collection API 架構範例
學習相關連結庫或 API,先理解主要架構是有必要的,這樣才不會淪於死背 API 或抄寫範
例的窘境。更進一步地,還可以從 API 中學習到良好設計的觀念,有了這樣的好習慣,以後對
新的 API 或連結庫就能更快地掌握如何使用甚至改進。
深入瞭解 JVM/JRE/JDK ,理解封裝、繼承、多型,掌握常用 Java SE API 架構,這都是
本書的說明重點。
4. 學習容器觀念
在步入 Java EE 領域之後,經常接觸到容器(Container)的觀念,許多人完全以 API 層次來
使用 Java EE 相關元件,這是不對的。就操作層面來說,容器是執行於 JVM 上的 Java 應用程
序;從抽象層面來說,就是應用程式溝通、協調相關資源的系統。
初次接觸容器的開發人員會覺得容器很抽象。以實際的例子來說,通常初學者步入 Java EE,
會從學習 Servlet/JSP 開始,而 Servlet/JSP 是執行於 Web 容器之中,這是學習容器時不錯的開始,
你必須知道“Web 容器是 Servlet/JSP 唯一認識的 HTTP 伺服器 ,是使用 Java 撰寫的應
用程式,執行於 JVM 之上” 。如果希望用 Servlet/JSP 撰寫的 Web 應用程式可以正常運作,
就必須知道 Servlet/JSP 如何與 Web 容器溝通, Web 容器如何管理 Servlet/JSP 的各種物件等
問題。
關於 Servlet/JSP 的說明,可參考我撰寫的《 JSP & Servlet 學習筆記 ( 2 ) ( 清華大學
出版社
) ,或是 Servlet/JSP 線上檔案:
/Gossip/ServletJSP/
容器無所不在, Applet 會執行於 Applet 容器中, 因此相關資源受到 Applet 容器的管理與限制,
Servlet/JSP 執行於 Web 容器中, EJB 執行於 EJB 容器中, Java 應用程式客戶端執行於應用程式客
戶端容器中,如圖 1.6 所示。不理解元件如何與容器互動,就無法真正使用或理解元件的行為。

圖 1.6 程式元件及其執行容器(摘自 )
5. 研究開放原始碼專案
Java 不僅是程式語言,也是個標準,在共同標準下有不同的執行方式,在 Java 領域的許多
操作都是以開放原始碼的方式存在, 只要你有興趣, 可以下載原始碼瞭解執行方式, 從中瞭解、
吸收他人設計、實現產品的技巧或理念。
許多基於 Java 各標準平臺發展出來的產品也值得研究,如測試框架(Framework)、 Web 框
架、持久層(Persistance)框架、物件管理容器等,這些產品補足標準未涵蓋之處,各有其設計上
的優秀與精良之處,有的已成為 Java 標準之一,它們多以開放原始碼的方式存在,讓開發人員
可以使用、研究甚至參與改進。
想要開始研究開放原始碼專案的使用與設計, JUnit 是個不錯的開始,可以參考線上檔案:
/Gossip/JUnit/
6. 學習設計模式 重構
在程式設計上,“經驗”是最重要的,在經驗傳承上,歸納而言,無非就是“如何根據需
求做出好的設計”“如何因應需求變化調整現有程式架構”,對於前者,流傳下來的設計經驗就
是設計模式(Design Pattern),對於後者,流傳下來的調整手法就是重構(Refactor)。
“如果我當初就這麼設計,現在就不會發生這個問題了!”這種對話應該很熟悉,“當初就
這麼設計”就是所謂設計模式。“如果我當初先這麼改,再那麼改,就不會把程式改到爛了!”
這種對話也經常聽到,“當初先這麼改,再那麼改”就是所謂重構。
無論好的設計還是不好的設計,都要有經驗傳承。經驗可以口耳相傳,可以從原始碼中觀
摩,也可以從書籍或網路上優秀的技術檔案中學得。對於初學者,從書籍或網路上優秀的技術
檔案學習設計模式與重構,是積累經驗的快捷方式。
7. 熟悉相關開發工具
除了累積足夠的實力與基礎,善用工具是必要的,開發工具可以避免煩瑣的指令、減少重
復性的操作、提示可用的 API、自動產生程式程式碼、降低錯誤的發生,甚至執行各種自動化的
測試、報告產生與傳送郵件等任務。有些開發人員鄙視開發工具,這是不必要的,兩個實力相
同的開發人員撰寫相同的應用程式,使用良好開發工具的人必然有較高的效率。
在 Java 領域難能可貴的是,存在不少優秀的開發工具,而且多以開放架構、開放原始碼的
方式存在,如 Eclipse IDE、 NetBeans IDE、 IntelliJ IDEA 都是相當不錯的選擇。還可以搭配 Ant
構建工具、 Maven 或 Gradle 專案工具等一起使用,大大地提升開發人員的產能。
建議初學 Java 的人,可以挑選一種開發工具來熟悉。所謂熟悉,不是指“下一步要按哪個
按鈕、接下來要執行哪個選單”,而是指這些開發工具相關操作是為了代勞你手動執行哪些指
令, 開發工具中的某些選項是為了代勞你設定哪些變數, 錯誤提示原本是來自 JDK 的什麼資訊,
等等。以這樣的過程來熟悉開發工具,才能善用開發工具提升產能,而不是受制於開發工具,
這樣即便換了另一套開發工具,也可以在最短時間內上手。
本書會使用 NetBeans IDE IDE 中的操作、設定與 JDK 指令的對照,是本書的重點之一。
1.2 JVM/JRE/JDK
本書一開始曾說,不要只從程式語言的角度來看 Java,這隻會看到“冰山一角”。這可以
用圖 1.7 來印證。

圖 1.7 Java 產品概念圖(摘自 )
如果安裝 JDK,就會安裝圖中所示全部的東西,而 Java Language 只是最左上角一小部分。
如果只是用短短几頁告訴你如何安裝 JDK、設定環境變數,而不解釋到底 JVM、 JRE 與 JDK
的作用與關係,你覺得夠嗎?
1.2.1 什麼是 JVM
在圖 1.7 中, Java Virtual Machine(JVM)會架構在 Linux、 Windows、 iOS 各種作業系統
平臺之上。許多 Java 的書都會告訴你, JVM 讓 Java 可以跨平臺,但是跨平臺是怎麼一回事,
在這之前,得先了解不能跨平臺是怎麼一回事。
對於計算機而言,只認識一種語言,也就是 、 1 序列組成的機器指令。當使用 C/C++等
高階語言撰寫程式時,其實這些語言是比較貼近人類可閱讀的文法,也就是比較接近英語文法
的語言。這是為了方便人類閱讀及撰寫,計算機其實看不懂 C/C++這類語言,為了將 C/C++翻
譯為 、 1 序列組成的機器指令,必須有個翻譯員。擔任翻譯員工作的就是編譯 程式
(Compiler),如圖 1.8 所示。

圖 1.8 編譯程式將程式翻譯為機器碼
問題在於,每個平臺認識的 、 1 序列並不一樣。某個指令在 Windows 上也許是 0101,在
Linux 下也許是 1010,因此必須使用不同的編譯程式為不同平臺編譯出可執行的機器碼,在
Windows 平臺上編譯好的程式,不能直接拿到 Linux 等其他平臺執行。也就是說,應用程式無
法達到“編譯一次,到處執行” 的跨平臺目的,如圖 1.9 所示。
Windows
編譯程式
Windows
編譯程式
Windows
編譯程式
Windows
Linux
Mac OS
Mac OS

圖 1.9 使用特定平臺編譯程式翻譯出對應的機器碼
Java 是個高階語言, 要讓計算機執行所撰寫的程式, 需要透過編譯程式的翻譯。 不過用 Java
編譯時,並不直接編譯為相依於某平臺的 、 1 序列,而是翻譯為中介格式的位碼(Byte Code)。
Java 原始碼副檔名為.java,經過編譯程式翻譯為副檔名為.class 的位碼。如果想要執行位
碼文件,目標平臺必須安裝 JVM(Java Virtual Machine)。 JVM 會將位碼翻譯為相依於平臺的機
器碼,如圖 1.10 所示。

不同的平臺必須安裝專屬該平臺的 JVM。這就好比你講中文(*.java), Java 編譯程式幫你翻
譯為英語(*.class),這份英語檔案到各個國家之後,再由當地看得懂英文的人(JVM)翻譯為當地
語言(機器碼)。
所以 JVM 擔任的職責之一就是
當地翻譯員,將位碼文件翻譯為當時
平臺看得懂的 、 1 序列。有了 JVM,
你的 Java 程式就可以達到“編譯一
次,到處執行” 的跨平臺目的。除
了了解 JVM 具有讓 Java 程式跨平臺
的重要任務之外,在撰寫 Java 程式
時,對 JVM 的重要認知就是:
對 Java 程式而言,只認識一
種作業系統,這個系統叫 JVM,
位碼文件(副檔名為.class 的文件)
就是 JVM 的可執行檔案。
Java 程式理想上並不用理會真正執行於哪個平臺,只要知道如何執行於 JVM 就可以了。
至於 JVM 實際上如何與底層平臺溝通,則是 JVM 自己的事。由於 JVM 實際上就相當於 Java
程式的作業系統, JVM 就負責了 Java 程式的各種資源管理。
瞭解“ JVM 就是 Java 程式的作業系統, JVM 的可執行檔案就是 .class 文件”非常重要,
對於以後理清所謂
PATH 變數與 CLASSPATH 變數之間的差別,有非常大的幫助。
1.2.2 區分 JRE 與 JDK
這裡再看一下第 2 章將學到的第一個 Java 程式,其中會有這麼一段程式程式碼:
System.out.println("Hello World");
前面曾經談過, Java 是個標準, System、 out、 println 都是標準中規範的名稱。實際上必須
要有人根據標準撰寫出 System.java, 編譯為 System.class, 這樣這些名稱才能在撰寫第一個 Java
程式時,使用
System 類(Class)上 out 物件(Object)的 println() 方法(Method)。
誰來操作 System.java?誰來編譯為.class?可能是 Oracle、 IBM、 Apache,無論如何,這些
廠商必須根據相關的 JSR 標準檔案將標準連結庫開發出來,這樣撰寫的第一個 Java 程式,在
Oracle、 IBM、 Apache 等廠商開發的 JVM 上執行時,引用如
System 這些標準 API,才可能輕
易地執行在不同的平臺。
在圖 1.7 中右側部分可以看到 Java SE API 涵蓋了各式常用的連結庫,像是通用的集合
(Collection)、輸入/輸出、聯機資料庫的 JDBC、撰
寫視窗程式的 Java FX 等,這些都是在各個 JSR 標
準檔案規範之中。
Java Runtime Environment 就是 Java 執行環
境, 簡稱 JRE, 包括 Java SE API 與 JVM。只要
使用 Java SE API 中的連結庫,在安裝有 JRE 的計
算機上就可以直接執行,無須額外在程式中再包裝
連結庫,而可以由 JRE 直接提供,如圖 1.11 所示。

圖 1.11 JRE 包括 Java SE API 與 JVM
java
編譯程式
位碼

Windows
Linux
Mac

在圖 1.7 中還可以看到,實際上 JRE 還包括了部署 (Deployment) 技術,也就是如何將程
序安裝到客戶端的技術,不過這不在本書介紹範圍內。建議直接檢視圖
1.7 摘自的網址,
其中有各種主題的檔案說明,可以善加利用。
前面說過,要在.java 中撰寫 Java 程式語言,使用編譯程式編譯為.class 文件,那麼像編譯
程式這樣的工具程式是由誰提供?答案就是 JDK,全名為 Java Developer Killer!呃!不對!是
Java Development Kit!
正如圖 1.7 所示, JDK 包括了 javac、 java、 javadoc 等工具程式,對於要開發 Java 程式的人,
必須安裝的是 JDK, 這樣才有這些工具程式可以使用, JDK 本身包括了 JRE, 這樣才能執行 Java
程式,所以總結就是“JDK 包括了 Java 程式語言、工具程式與 JRE, JRE 則包括了部署
技術、 Java SE API 與 JVM” ,這也就是圖 1.2 想表達的含義。
撰寫 Java 程式才需要 JDK,如果你的程式只是想讓朋友執行呢?那他只要裝 JRE 就可以
了,不用安裝 JDK,因為他不需要 javac 這些工具程式,但他需要 Java SE API 與 JVM。
對初學者來說, JDK 確實很不友善,這大概是 Java 陣營的哲學,它會假設你懂得如何準備
相關開發環境,因此裝好 JDK 之後,該自己設定的變數或選項就要自己設定, JDK 不會代勞,
過去戲稱 JDK 全名為 Java Developer Killer 其實是有其來源的。
瞭解 Java SE 中 JVM、 JRE 與 JDK 的關係之後,接下來應該來點實際操作了。第一步就是
下載、安裝 JDK。
1.2.3 下載、安裝 JDK
要下載 JDK,請連結到(Java SE Downloads)以下網址:

你要下載的是 Java SE 9 中的 JDK,按照以往慣例,釋出 JDK 之後,每隔幾個月會針對使
用者反饋的 BUG 或安全問題進行修正,併釋出一個修正版 JDK。在過去,如果你連線以上網
址時,出現的字樣是 Java SE Development XuN 之類的字樣,其中 X 會是重大特性發布用的號
碼,像是 8、 9 等號碼,也就是代表 Java SE 8、 Java SE 9 等, N 就是 BUG 或安全問題更新版本
號。圖 1.12 所示為 JDK 的下載頁面。

圖 1.12 JDK 下載頁面
然而, Oracle 在 Oracle Java SE Support Roadmap 中提出了新的特性版本釋出方式,不再是
基於重大特性來發布版本,而是改為基於時間、以半年為週期、持續釋出小特性的版本,讓一
些對開發者有用的小特性,可以在這些新版本中放出,而這些版本將會是短期支援版本,在下
個小特性版本釋出之後,上個版本就不再維護,使用者要趕快更新至新版本。
有些語言也是持續而頻繁地釋出新版本,比如 Go 語言,基於時間而非基於重大特性來發布
的軟體,最典型的範例就是
Ubuntu
除了短期支援版本之外,
Oracle 也有 Java SE 的長期支援版本,基本上以 3 年為週期,可以
透過
Oracle Java SE Advanced Oracle Java SE Advanced Desktop Java SE Suite 取得。另
外,
Java SE 8 會是個長期支援版本, 將支援至 2022 年, 詳情可以參考 Oracle Java SE Support
Roadmap
中的說明:
雖然未來 JDK 在小特性版本釋出時,預計採用 $YEAR.$MONTH 格式,不過看來尚有討論空
間,詳情可看:
mail.openjdk.java.net/pipermail/jdk-dev/2017-October/000007.html
在網頁中還可以看到 Server JRE 與 JRE 的下載。前面提過,使用者如果要執行 Java 程式,只
需要安裝 JRE,不需要安裝 JDK,其中客戶端應用程式可以下載 JRE 版本,如果是要執行服務
器端應用程式,可以下載 Server JRE 版本。
單擊 JDK 的 Download 按鈕,會進入另一個頁面。必須先選中 Accept License Agreement(同
意許可協議)單選按鈕,接著選擇對應作業系統版本的 JDK。以 Windows x64 為例,單擊
jdk-9_windows-x64_bin.exe 就可以下載 JDK,如圖 1.13 所示。

圖 1.13 開始下載 JDK
下載完成後,雙擊文件就可以看到啟始安裝畫面,直接單擊“下一步”按鈕看到圖 1.14 所
示對話方塊。
開發工具(Development Tools)就是安裝編譯程式之類的工具程式,要開發 Java 程式,就
得安裝它。原始碼 (Source Code)是 JRE 中 Java SE API 的操作程式程式碼,有時候,你會需要查
看 Java SE API 原始碼,瞭解一下內部運作機制。公共 JRE(Public JRE)就是剛剛在圖 1.12
中看到的 JRE,所以下載了 JDK,就同時下載了 JRE。
除了“開發工具”之外,另外兩個選項,其實都可以不安裝,這不影響後續的程式開發。
不過為了以後可以參考一些原始碼、直接在“公共 JRE”上測試等,或開發簡單的資料庫程
序,建議選擇“全部安裝”選項。
不安裝 Public JRE?那怎麼執行寫好的 Java 程式呢?不是說要有 JRE 才可以執行嗎?其實
JDK 本身附有一個 JRE,相對於 Public JRE 這個名稱,JDK 自己附的 JRE 通常稱為 Private JRE,
只要安裝 JDK,一定就有 Private JRE,稍後會說明 Private JRE 的安裝位置。安裝 Public JRE 或
自行下載 JRE 安裝,會註冊 Java Plugin、 Web Start 等瀏覽器或桌面客戶端必要的元件,方便需
要 JRE 的應用程式使用。
在安裝時注意圖 1.14 中“安裝到”的位置,必須記住 JDK 安裝位置,之後設定
PATH 變數
時會用到這個資訊。單擊圖 1.14 中的“下一步”按鈕,等待 JDK 安裝完後,若在圖 1.14 中選
擇安裝“公共 JRE”,就會再出現安裝 Public JRE 的畫面,同樣地,請記下安裝位置,如圖 1.15
所示。

基於安全原因, Oracle 曾宣佈將停止瀏覽器外掛:
http://blogs. oracle.com/java-platform- group/ moving- to-a-plugin-free-web
就本章撰寫期間,是否啟用瀏覽器中的 Java 支援,這就交給使用者來決定,在臺灣仍有
些金融機構會採用
Applet 來提供網路銀行之類的服務,如果你沒有這類需求,在圖 1.15
中可以不選中“啟用瀏覽器中的 Java 內容”核取方塊。
裝好 JDK 之後,在 Windows 7 或 Windows 後續版本中,可以在“開始”選單中執行“所
有程式” |“附件” |“命令提示符”命令,啟動“命令提示符”視窗。在 Windows 10 中,可以
直接在“開始”介面輸入 cmd 啟動“命令提示字元”,接著輸入 java,看到圖 1.16 所示介面,
表示 JDK 初步安裝完成。

圖 1.16 檢視 JDK 是否安裝完成
為什麼說 JDK 初步安裝完成?因為還要設定 PATH 環境變數, 這要在第 2 章中再做說明。
1.2.4 認識 JDK 安裝內容
那麼你到底安裝了哪些東西呢?假設 JDK 與 Public JRE 各安裝至 C:\Program Files\Java\jdk-
9.0.4\及 C:\Program Files\Java\jre-9.0.4(如果安裝時有選擇“公共 JRE”選項的話)。
Public JRE 是給 Java 程式執行的平臺, JDK 本身也附帶 JRE,通常被稱為 Private JRE。如
果你熟悉 Java SE 8 或者之前版本的 Java,可能會想 Private JRE 應該還是在 JDK 安裝資料夾中
的 jre 資料夾中。不過, Java SE 9 改變了 JDK 與 Public JRE 的資料夾內容, JDK 安裝資料夾中
沒有專用的 jre 資料夾來放 Private JRE 了,只要記得 JDK 資料夾中包含 JRE 的內容就可以了(以
及 JVM)。除此之外,也看不到過去 JDK 版本安裝後會有的 rt.jar 與 tools.jar。
圖 1.17 中可以對照圖 1.14 的部分, bin 資料夾中存放的就是 Development Tools,包括了
編譯 Java 原始碼的
javac ,執行 Java 程式的 java 等工具程式。

圖 1.17 JDK 安裝資料夾
至於 Source Code 選項,也就是 Java SE API 執行原始碼的部分,可以在 lib 資料夾中的 src.zip
中找到,使用解壓縮軟體解開,就能看到許多資料夾,它們對應至 Java SE 9 的模組平臺系統劃
分出來的各個模組,而在這些資料夾中會有許多.java 原始碼文件。
那麼 Java SE API 編譯好的.class 文件放在哪裡呢? Java SE 9 的模組平臺系統為了改進效
率、安全與維護性,使用了模組執行時期映像(Modular Run-Time Images),又稱 JIMAGE,無
論是 JDK 或 Public JRE 的資料夾中, 都會有個 lib 資料夾, 其中有個 modules 文件, 包含了.class
文件的執行時期格式。
可以使用 jlink 來建立專用的執行時期映像,其中只包含你使用到的模組, 19.3 節會介紹這
些模組如何建立;
modules 文件中的 .class 文件是可以取出的,如果有興趣的話,可以檢視
下 面 的 鏈 接 :
http://blogs.oracle.com/sundararajan/extracting-a-single-class-file-from-ava9-
platform-jimage-modules-file
至於在編譯時期, Java SE 9 引入了新的 JMOD 格式來封裝模組,副檔名為.jmod,這些文
檔位於 JDK 資料夾中的 jmods 資料夾,每個模組對應的.jmod 中就包括了編譯完成的.class 文件。
在過去, JAR(Java Archive) 文件是封裝 .java .class 文件的主要格式,有許多開發工具
都能自動為使用者建立
JAR 文件,而在文字模式下,還可以使用 JDK jar 工具程式來制
JAR 檔案, 19.3 節會介紹如何使用 jar 工具程式。
JMOD 格式可以包含比 JAR 文件更多的資訊,如原生指令、連結庫等, JDK9 本身包含
jmod 工具程式,可以用來建立 JMOD 文件,或者從 JMOD 文件中取得封裝的內容 (
前實際上只是
ZIP 壓縮,然而未來可能改變 ) 19.3 也會介紹如何使用 jmod 工具程式。
你可以回頭對照圖 1.7,問問自己,現在是不是記住 JDK、 JRE、 Java SE API 與 JVM 的安
裝位置了呢?
因為 Java SE 9 JDK/JRE 在文件實體佈局上,有別於過去的 Java SE 版本,如果你曾
在舊版
JDK 上使用相關開發工具撰寫過 Java 程式,在升級至 Java SE 9 之後,相關開發
工具可能會因此而在執行上有問題,若是如此,請確認你的開發工具是否有針對
JDK9
的升級版本。
1.3 重點複習
Java 最早是 Sun 公司“綠色專案” (Green Project)中撰寫 Star7 應用程式的程式語言,當時
名稱不是 Java,而是取名為 Oak。全球資訊網興起, Java Applet 成為網頁互動技術代表。 1995
年 5 月 23 日,正式將 Oak 改名為 Java, Java Development Kits(當時的 JDK 全名)1.0a2 版本正式
對外發表。
Java 2 名稱從 J2SE 1.2 一直沿用至之後各個版本,直到 2006 年 12 月 11 日的 Java Platform,
Standard Edition 6,改稱 Java SE 6, JDK6 全名則稱為 Java SE Development Kit 6,也就是不再
像 Java 2 帶有 2 這個號碼。
2010 年, Oracle 宣佈併購 Sun, Java 正式成為 Oracle 所屬。
Java 根據應用領域不同,區分為 Java SE、 Java EE 與 Java ME 三大平臺。 Java SE 是各應用
平臺的基礎,分為四個主要的部分: JVM、 JRE、 JDK 與 Java 語言。 JDK 包括 Java 程式語言、
JRE 與開發工具, JRE 包括 Java SE API 與 JVM。
JCP 是個開放性國際組織,目的是讓 Java 演進由 Sun 非正式地主導,成為全世界數以百計
代表成員公開監督的過程。任何想要提議加入 Java 的功能或特性,必須以 JSR 正式檔案的方式
提交,經過 JCP 執行委員會投票透過,方可成為最終標準檔案,有興趣的廠商或組織可以根據
JSR 實現產品。
若 JSR 成為最終檔案後,必須根據 JSR 成果做出免費且開發原始碼的參考實現,稱為
RI(Reference Implementation), 並提供 TCK(Technology Compatibility Kit)作為技術相容測試工具
箱,方便其他想根據 JSR 實現產品的廠商或組織參考與測試相容性。
只有透過 TCK 相容性測試的實現,才可以使用 Java 這個商標。
在 2006 年的 JavaOne 大會上,Sun 宣告對 Java 開放原始碼,從 JDK7 b10 開始有了 OpenJDK,
並於 2009 年 4 月 15 日正式釋出 OpenJDK。Oracle 時代釋出的 JDK7 正式版本,指定了 OpenJDK7
為官方參考實現。
OpenJDK6 並不是 Sun JDK6 的分支,而是將 OpenJDK7 中 JDK7 的特性刪掉,使之符合 JDK6
的規範,因而 OpenJDK6 實際上是 OpenJDK7 的分支。
Java 編譯時並不直接編譯為相依於某平臺的 、 1 序列,而是翻譯為中介格式的位碼(Byte
Code)。對 Java 程式而言,只認識一種作業系統,這個系統叫 JVM,位碼文件(副檔名為.class
的文件)就是 JVM 的可執行檔案。
Java Runtime Environment 就是 Java 執行環境,簡稱 JRE,包括 Java SE API 與 JVM。只要
使用 Java SE API 中的連結庫,在安裝有 JRE 的計算機上就可以直接執行,無須額外在程式中
再包裝連結庫,而由 JRE 直接提供。
JDK 本身附有一個 JRE,相對於 Public JRE 這個名稱,JDK 所附的 JRE 通常稱為 Private JRE,
只要安裝 JDK,一定就有 Private JRE。安裝 Public JRE 或自行下載 JRE 安裝,會註冊 Java Plugin、
Web Start 等瀏覽器或桌面客戶端必要的元件,方便需要 JRE 的桌面應用程式使用。

購買地址:


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26421423/viewspace-2217185/,如需轉載,請註明出處,否則將追究法律責任。

相關文章