本目錄收錄《Java 程式設計完整學習教材》進階篇 ch01~ch08 全部 82 個範例, 皆可獨立編譯(已於 OpenJDK 21 驗證),並保留書中的繁體中文教學註解。 每個檔案第一行的 // 出處:… 註明對應的章節。

執行方式

cd code
./run.sh advanced/<章節目錄> <主類別名>
# 例如:
./run.sh advanced/ch01-lambda-functional LambdaDemo
./run.sh advanced/ch08-design-patterns-modern-java ExprEval

需 JDK 21(虛擬執行緒、switch 模式匹配與 record 解構為 21 的正式功能)。

本冊特殊範例注意事項

  • 多執行緒範例(ch03、ch04):輸出的交錯順序、執行緒與任務的對應 每次執行都可能不同,屬預期行為;書中輸出僅為其中一種可能。
  • 死結範例 DeadlockDemo(ch03):本範例會永久卡住,屬預期行為, 請以 Ctrl+C 結束。可另開終端機用 jps 找出程序號、jstack <pid> 觀察死結報告(會印出 Found one Java-level deadlock,即第 6 章 6.7 節的示範)。
  • OOM 示範 HeapOOM(ch06):請用小堆積執行,建議 java -Xmx64m -XX:+UseSerialGC HeapOOM。詳見 ch06 備註。
  • 網路範例(ch07):伺服器與用戶端要開兩個終端機分別執行; macOS 若開啟「AirPlay 接收器」會佔用 TCP 5000 埠,導致 EchoServer/PooledEchoServer 拋出 BindException: Address already in use,請先到系統設定關閉 AirPlay 接收器(或自行改埠測試)。
  • HttpClient 範例(ch07):實際執行需要網際網路連線,本目錄僅驗證 編譯;離線執行會拋出連線例外。
  • JDBC 範例(ch07):java.sql 為 JDK 內建,編譯不需任何依賴; 實際執行需先下載 SQLite JDBC 驅動(org.xerial:sqlite-jdbc)JAR, 再以 java -cp ".:sqlite-jdbc-<版本>.jar" JdbcCrud 執行(或把連線 字串改為 MySQL)。書中的執行結果為示意輸出。

ch01 Lambda 與函數式程式設計(13 個)

檔案 內容說明 執行方式 備註
NamedClassDemo.java 具名類別實作 Runnable run.sh
AnonymousClassDemo.java 匿名類別實作 Runnable run.sh
LambdaDemo.java Lambda 實作 Runnable run.sh
CalculatorDemo.java 自訂函數式介面與預設方法 run.sh 書中標題為 Calculator.java,因公開類別名而改名
FunctionDemo.java Function 的 apply/andThen/compose run.sh
PredicateDemo.java Predicate 的 test/and/or/negate run.sh
ConsumerSupplierDemo.java Consumer 與 Supplier run.sh
MethodRefDemo.java 四種方法參考 run.sh
CaptureDemo.java 變數捕獲與 effectively final run.sh
ComparatorDemo.java Comparator 多鍵排序 run.sh 部門升冪依 Unicode 碼位「研發」在「行銷」前,與書中輸出順序不同(見文末)
OptionalBasics.java Optional 建立與 map/filter/orElse run.sh
OrElseVsOrElseGet.java orElse 與 orElseGet 求值時機 run.sh
PasswordValidator.java Predicate 組合驗證器 run.sh

ch02 Stream API(12 個)

檔案 內容說明 執行方式 備註
ImperativeStyle.java 命令式寫法對照組 run.sh
DeclarativeStyle.java 宣告式(Stream)寫法 run.sh
CreateStream.java 六種建立 Stream 的方式 run.sh
FlatMapDemo.java flatMap 攤平巢狀結構 run.sh
LazyEvaluation.java peek 觀察惰性求值 run.sh
TerminalOps.java 比對/搜尋/極值終端操作 run.sh
ReduceDemo.java reduce 三種形式 run.sh
CollectorsBasics.java joining 與 toMap 合併函式 run.sh
GroupingDemo.java groupingBy 單層/下游/巢狀 run.sh Map 印出順序不保證,內容與書中一致
PrimitiveStream.java IntStream 與 summaryStatistics run.sh
ParallelPitfall.java 平行流共享可變狀態的錯誤 run.sh 錯誤寫法筆數每次不同(甚至可能拋例外),屬預期的反面教材
EmployeeAnalytics.java 員工資料多維度分析 run.sh Map 印出順序不保證

ch03 多執行緒基礎(11 個)

檔案 內容說明 執行方式 備註
ThreadBySubclass.java 繼承 Thread 建立執行緒 run.sh
ThreadByRunnable.java Runnable 與 Lambda 寫法 run.sh 兩行輸出順序不定
ThreadStateDemo.java 觀察執行緒六種狀態 run.sh
JoinDemo.java join 等待工作完成 run.sh
DaemonDemo.java 守護執行緒背景心跳 run.sh 心跳次數視時間而定
InterruptDemo.java 正確回應中斷 run.sh 「工作中…」次數視時間而定
RaceCondition.java 競態條件(遺失更新) run.sh 實際值每次不同且小於 200000,屬預期
SyncCounter.java synchronized 修正競態 run.sh
VolatileDemo.java volatile 可見性 run.sh 累計值每次不同
ProducerConsumer.java wait/notify 生產者消費者 run.sh 交錯順序每次不同,總量各 5
DeadlockDemo.java 交叉取鎖造成死結 run.sh 會永久卡住,屬預期行為,Ctrl+C 結束;可用 jstack 觀察死結報告

ch04 並行程式設計進階(12 個)

檔案 內容說明 執行方式 備註
ExecutorBasics.java 執行緒池提交任務與標準關閉 run.sh 任務與執行緒對應順序不定
CustomPool.java 手動配置 ThreadPoolExecutor run.sh 排程順序不定
FutureDemo.java Callable 與 Future run.sh
CompletableFutureBasics.java thenApply/thenCompose/thenCombine run.sh
CompletableFutureError.java exceptionally 例外處理 run.sh
AsyncPipeline.java 並行查詢合併與耗時量測 run.sh 總耗時約 200~300 毫秒
AtomicCounter.java AtomicInteger 免鎖計數 run.sh
TryLockDemo.java tryLock 帶逾時取鎖 run.sh 實測兩執行緒會先後取得鎖,與書中輸出不同(見文末)
ConcurrentMapDemo.java ConcurrentHashMap 的 merge run.sh
BlockingQueueDemo.java BlockingQueue 生產者消費者 run.sh 交錯順序每次不同
CountDownLatchDemo.java CountDownLatch 等待多工 run.sh
VirtualThreadDemo.java 虛擬執行緒(Java 21) run.sh 完成順序不固定

ch05 反射與標註(7 個)

檔案 內容說明 執行方式 備註
GetClassObject.java 三種取得 Class 物件 run.sh
InspectClass.java 走訪欄位與方法 run.sh getDeclaredMethods 順序不保證,方法列出順序可能與書中相反
DynamicInvoke.java 動態建立實體/呼叫/改私有欄位 run.sh
Column.java 自訂標註 @Column 的定義 僅編譯(無 main) 書中 5.6 節的定義列表;執行期讀取見 ReadAnnotation
ReadAnnotation.java 反射讀取欄位標註 run.sh
MiniTest.java 迷你測試框架(仿 JUnit) run.sh 方法掃描順序不保證
MiniInjector.java 迷你依賴注入(仿 Spring) run.sh

ch06 JVM 深入剖析(6 個)

檔案 內容說明 執行方式 備註
ClassInit.java 類別初始化觸發時機 run.sh
ClassLoaderDemo.java 類別載入器階層 run.sh @ 後的雜湊值因執行而異
StackOverflow.java 無窮遞迴撐爆堆疊 run.sh 深度視 -Xss 而定(實測約 1.5 萬~2 萬);可用 java -Xss256k 觀察更小深度
HeapOOM.java 堆積溢位示範 java -Xmx64m -XX:+UseSerialGC HeapOOM 用 Serial/Parallel GC 可看到書中訊息(實測約 56~60 MB);JDK 21 預設 G1 下 catch 內字串串接常再度 OOM,訊息印不出、直接顯示未捕捉的 OutOfMemoryError(教學點仍成立)。-Xmx16m 亦可快速觀察
ReferenceDemo.java 弱引用被 GC 回收 run.sh
MemoryLeak.java static 集合造成洩漏 run.sh

6.7 節的 jps/jstack 示範沒有獨立程式,請對 ch03 的 DeadlockDemo 操作即可重現(輸出中的監視器位址等因環境而異)。GC 日誌示範可用 java -Xlog:gc 搭配任一範例觀察,輸出因環境而異。

ch07 網路程式設計與 JDBC(12 個)

檔案 內容說明 執行方式 備註
InetAddressDemo.java 查詢本機與主機 IP run.sh 輸出為本機環境值,與書中示意不同屬正常
EchoServer.java 單執行緒回聲伺服器(5000 埠) 見下方兩終端機步驟 macOS 需先關閉 AirPlay 接收器
EchoClient.java 回聲用戶端 見下方兩終端機步驟
PooledEchoServer.java 執行緒池回聲伺服器(5000 埠) 同上,可多開用戶端 無限迴圈,Ctrl+C 結束
ChatServer.java 群聊廣播伺服器(6000 埠) 伺服器 + 多個 nc localhost 6000 無限迴圈,Ctrl+C 結束;已實測兩用戶端廣播
UdpDemo.java UDP 收發(7000 埠,單程式) run.sh AirPlay 佔用的是 TCP 7000,不影響本範例的 UDP
HttpClientDemo.java HttpClient 同步/非同步請求 需網路連線 僅驗證編譯;離線會拋連線例外
JdbcCrud.java JDBC 建表與 CRUD 需 SQLite 驅動 java -cp ".:sqlite-jdbc-<版本>.jar" JdbcCrud
SqlInjection.java SQL 注入示範(僅字串) run.sh 不需資料庫
PreparedStatementDemo.java 參數化查詢 需 SQLite 驅動 先跑 JdbcCrud 建表
TransferDemo.java 交易與回滾 需 SQLite 驅動 需先自建 account 表
StudentDao.java DAO 模式與批次寫入 僅編譯(無 main) 書中列表即無 main,展示 DAO 結構;書中輸出為呼叫 saveAll 的示意

Echo 範例的兩終端機步驟(伺服器服務完一條連線即結束):

# 終端機 1:啟動伺服器(macOS 請先關閉 AirPlay 接收器)
./run.sh advanced/ch07-network-jdbc EchoServer

# 終端機 2:啟動用戶端,送出兩行訊息並印出回聲
./run.sh advanced/ch07-network-jdbc EchoClient

群聊範例:終端機 1 跑 ChatServer,終端機 2、3 各跑 nc localhost 6000,任一邊輸入文字,所有用戶端都會收到。

ch08 設計模式與現代 Java(9 個)

檔案 內容說明 執行方式 備註
OpenClosed.java 開放封閉原則 run.sh
Singletons.java 單例多種寫法(餓漢/雙重檢查/靜態內部類別) run.sh 三種寫法為同檔巢狀類別,無需分目錄
FactoryMethod.java 工廠方法模式 run.sh
BuilderDemo.java 建造者模式 run.sh
StrategyDemo.java 策略模式(Lambda 版) run.sh
ObserverDemo.java 觀察者模式 run.sh
DecoratorDemo.java 裝飾者模式 run.sh
RecordDemo.java record 與 text block run.sh
ExprEval.java sealed + record + switch 模式匹配 run.sh 需 JDK 21

未抽出片段

無。書中 82 個程式列表(javacode 區塊)全數抽出;其中 Column.java 與 StudentDao.java 依書中原樣無 main 方法,屬「僅編譯」的結構示範。 內文以文字描述的零星程式片段(如 Stream 重複消費的條列、jstack 指令 操作)不屬程式列表,未列入抽出範圍。

與書中輸出的已知差異

  1. ch01 ComparatorDemo:部門「升冪」依 Java 字串自然排序 (Unicode 碼位),「研發」(U+7814) 排在「行銷」(U+884C) 之前; 實際輸出研發組在前,書中誤將行銷組排在前。
  2. ch04 TryLockDemo:持鎖時間 300 毫秒短於 tryLock 逾時 500 毫秒,後到的執行緒會等到鎖釋放後成功取得;實測(多次)皆為 「A 取得鎖/B 取得鎖」先後出現,書中「B 放棄取鎖」在此參數下 不會發生。
  3. ch06 HeapOOM:JDK 21 預設 G1 下,catch 區塊內的字串串接 會再度 OOM,導致書中訊息未印出;改用 -XX:+UseSerialGC 可重現 書中輸出。
  4. 其餘差異皆屬書中已註明的非決定性(執行緒交錯、Map 順序、 反射順序、環境相關數值),內容語意與書中一致。