內容簡介
《Java編程思想》:
從《Java編程思想》獲得的各項大奬以及來自世界各地的讀者評論中,不難看齣本書是一本經典之作。《Java編程思想》的作者擁有多年教學經驗,對C、C++以及Java語言都有獨到、深入的見解,以通俗易懂及小而直接的示例解釋瞭一個個晦澀抽象的概念。《Java編程思想》共22章,包括操作符、控製執行流程、訪問權限控製、復用類、多態、接口、通過異常處理錯誤、字符串、泛型、數組、容器深入研究、JavaI/O係統、枚舉類型、並發以及圖形化用戶界麵等內容。這些豐富的內容,包含瞭Java語言基礎語法以及高級特性,適閤各個層次的Java程序員閱讀,同時也是高等院校講授麵嚮對象程序設計語言以及Java語言的好教材和參考書。
《自己動手寫JAVA虛擬機》:
Java虛擬機非常復雜,要想真正理解它的工作原理,好方式就是自己動手編寫一個!
張秀宏編著的《自己動手寫Java虛擬機》是繼《深入理解Java虛擬機》之後的又一經典著作,它一方麵遵循《Java虛擬機規範》,一方麵又獨闢蹊徑,不僅能讓Java虛擬機的學習變得更加簡單和有趣,而且能讓你對Java虛擬機的原理認識更深入和更深刻!
《自己動手寫JAVA虛擬機》摒棄瞭傳統的以解讀枯燥的Java虛擬機規範文檔和分析繁瑣的Java虛擬機源代碼的方式來講解Java虛擬機,取而代之的是,以實踐的方式,引導讀者如何從零開始構建和實現一個Java虛擬機。整個過程不僅能讓讀者做到對Java虛擬機知其然而且知其所以然,還能屏蔽大量不必要的繁瑣細節,體會到實現過程中的成就感,讓學習過程更加輕鬆、愉悅和高效。更重要的是,這種方式能引導讀者更深入地認識和掌握Java虛擬機的工作原理。
作者簡介
Bruce Eckel,Mind View公司(www.MirldView.net)的總裁,該公司嚮客戶提供軟件谘詢和培訓。他是C++標準委員會擁有錶決權的成員之一,擁有應用物理學學士和計算機工程碩士學位。除本書外,他還是《C++編程思想》的作者,並與人閤著瞭《C++編程思想第2捲》(這兩本書的英文影印版及中文版均已由機械工業齣版社引進齣版)及其他著作。他已經發錶瞭150多篇論文,還經常參加世界各地的研討會並進行演講。
張秀宏,Java服務器開發工程師,有多年的Java開發、遊戲服務器開發和架構經驗,對Java虛擬機有非常深入的研究。曾在EA、華娛無綫等遊戲公司擔任高級服務器工程師職位,現任樂元素Lead軟件工程師。
內頁插圖
目錄
《Java編程思想》:
齣版者的話
專傢指導委員會
讀者評論
關於《Thinking in C++》
譯者序
譯者簡介
前言
緒論
第1章 對象導論
1.1 抽象過程
1.2 每個對象都有一個接口
1.3 每個對象都提供服務
1.4 被隱藏的具體實現
1.5 復用具體實現
1.6 繼承
1.6.1 “是一個”與“像是一個”關係
1.7 伴隨多態的可互換對象
1.8 單根繼承結構
1.9 容器
1.9.1 參數化類型(範型)
1.10 對象的創建和生命期
1.11 異常處理:處理錯誤
1.12 並發編程
1.13 Java與Internet
1.13.1 Web是什麼
1.13.2 客戶端編程
1.13.3 服務器端編程
1.14 總結
第2章 一切都是對象
2.1 用引用操縱對象
2.2 必須由你創建所有對象
2.2.1 存儲到什麼地方
2.2.2 特例:基本類型
2.2.3 Java中的數組
2.3 永遠不需要銷毀對象
2.3.1 作用域
2.3.2 對象的作用域
2.4 創建新的數據類型:類
2.4.1 字段和方法
2.5 方法、參數和返迴值
2.5.1 參數列錶
2.6 構建一個Java程序
2.6.1 名字可見性
2.6.2 運用其他構件
2.6.3 static 關鍵字
2.7 你的第一個Java程序
2.7.1 編譯和運行
2.8 注釋和嵌入式文檔
2.8.1 注釋文檔
2.8.2 語法
2.8.3 嵌入式HTML
2.8.4 一些標簽示例
2.8.5 文檔示例
2.9 編碼風格
2.10 總結
2.11 練習
第3章 操作符
3.1 更簡單的打印語句
3.2 使用Java操作符
3.3 優先級
3.4 賦值
3.4.1 方法調用中的彆名問題
3.5 算術操作符
3.5.1 一元加、減操作符
3.6 自動遞增和遞減
3.7 關係操作符
3.7.1 測試對象的等價性
3.8 邏輯操作符
3.8.1 短路
3.9 直接常量
3.9.1 指數記數法
3.10 按位操作符
3.11 移位操作符
3.12 三元操作符 if-else
3.13 字符串操作符 + 和 +=
3.14 使用操作符時常犯的錯誤
3.15 類型轉換操作符
3.15.1 截尾和捨入
3.15.2 提升
3.16 Java沒有sizeof
3.17 操作符小結
3.18 總結
第4章 控製執行流程
4.1 true和false
4.2 if-else
4.3 迭代
4.3.1 do-while
4.3.2 for
4.3.3 逗號操作符
4.4 Foreach語法
4.5 return
4.6 break和 continue
4.7 臭名昭著的goto
4.8 switch
4.9 總結
第5章 初始化與清理
5.1 用構造器確保初始化
5.2 方法重載
5.2.1 區分重載方法
5.2.2 涉及基本類型的重載
5.2.3 以返迴值區分重載方法
5.3 默認構造器
5.4 this關鍵字
5.4.1 在構造器中調用構造器
5.4.2 static的含義
5.5 清理:終結處理和垃圾迴收
5.5.1 finalize()的用途何在
5.5.2 你必須實施清理
5.5.3 終結條件
5.5.4 垃圾迴收器如何工作
5.6 成員初始化
5.6.1 指定初始化
5.7 構造器初始化
5.7.1 初始化順序
5.7.2 靜態數據的初始化
5.7.3 顯式的靜態初始化
5.7.4 非靜態實例初始化
5.8 數組初始化
5.8.1 可變參數列錶
5.9 枚舉類型
5.10 總結
第6章 訪問權限控製
6.1 包:庫單元
6.1.1 代碼組織
6.1.2 創建獨一無二的包名
6.1.3 定製工具庫
6.1.4 用 import改變行為
6.1.5 對使用包的忠告
6.2 Java訪問權限修飾詞
6.2.1 包訪問權限
6.2.2 public:接口訪問權限
6.2.3 private: 你無法訪問
6.2.4 protected:繼承訪問權限
6.3 接口和實現
6.4 類的訪問權限
6.5 總結
第7章 復用類
7.1 組閤語法
7.2 繼承語法
7.2.1 初始化基類
7.3 代理
7.4 結閤使用組閤和繼承
7.4.1 確保正確清理
7.4.2 名稱屏蔽
7.5 在組閤與繼承之間選擇
7.6 protected關鍵字
7.7 嚮上轉型
7.7.1 為什麼稱為嚮上轉型
7.7.2 再論組閤與繼承
7.8 final關鍵字
7.8.1 final 數據
7.8.2 final 方法
7.8.3 final 類
7.8.4 有關final的忠告
7.9 初始化及類的加載
7.9.1 繼承與初始化
7.10 總結
第8章 多態
8.1 再論嚮上轉型
8.1.1 忘記對象類型
8.2 轉機
8.2.1 方法調用綁定
8.2.2 産生正確的行為
8.2.3 可擴展性
8.2.4 缺陷:“覆蓋”私有方法
8.2.5 缺陷:域與靜態方法
8.3 構造器和多態
8.3.1 構造器的調用順序
8.3.2 繼承與清理
8.3.3 構造器內部的多態方法的行為
8.4 協變返迴類型
8.5 用繼承進行設計
8.5.1 純繼承與擴展
8.5.2 嚮下轉型與運行時類型識彆
8.6 總結
第9章 接口
9.1 抽象類和抽象方法
9.2 接口
9.3 完全解耦
9.4 Java中的多重繼承
9.5 通過繼承來擴展接口
9.5.1 組閤接口時的名字衝突
9.6 適配接口
9.7 接口中的域
9.7.1 初始化接口中的域
9.8 嵌套接口
9.9 接口與工廠
9.10 總結
第10章 內部類
10.1 創建內部類
10.2 鏈接到外部類
10.3 使用.this與.new
10.4 內部類與嚮上轉型
10.5 在方法和作用域內的內部類
10.6 匿名內部類
10.6.1 再訪工廠方法
10.7 嵌套類
10.7.1 接口內部的類
10.7.2 從多層嵌套類中訪問外部類的
成員
10.8 為什麼需要內部類
10.8.1 閉包與迴調
10.8.2 內部類與控製框架
10.9 內部類的繼承
10.10 內部類可以被覆蓋嗎
10.11 局部內部類
10.12 內部類標識符
10.13 總結
第11章 持有對象
11.1 泛型和類型安全的容器
11.2 基本概念
11.3 添加一組元素
11.4 容器的打印
11.5 List
11.6 迭代器
11.6.1 ListIterator
11.7 LinkedList
11.8 Stack
11.9 Set
11.10 Map
11.11 Queue
11.11.1 PriorityQueue
11.12 Collection和Iterator
11.13 Foreach與迭代器
11.13.1 適配器方法慣用法
11.14 總結
第12章 通過異常處理錯誤
12.1 概念
12.2 基本異常
12.2.1 異常參數
12.3 捕獲異常
12.3.1 try塊
12.3.2 異常處理程序
12.4 創建自定義異常
12.4.1 異常與記錄日誌
12.5 異常說明
12.6 捕獲所有異常
12.6.1 棧軌跡
12.6.2 重新拋齣異常
12.6.3 異常鏈
12.7 Java標準異常
12.7.1 特例:RuntimeException
12.8 使用finally進行清理
12.8.1 finally用來做什麼
12.8.2 在return中使用finally
12.8.3 缺憾:異常丟失
12.9 異常的限製
12.10 構造器
12.11 異常匹配
12.12 其他可選方式
12.12.1 曆史
12.12.2 觀點
12.12.3 把異常傳遞給控製颱
12.12.4 把“被檢查的異常”轉換為“不受
檢查的異常”
12.13 異常使用指南
12.14 總結
第13章 字符串
13.1 不可變String
13.2 重載“+”與StringBuilder
13.3 無意識的遞歸
13.4 String上的操作
13.5 格式化輸齣
13.5.1 printf()
13.5.2 System.out.format()
13.5.3 Formatter類
13.5.4 格式化說明符
13.5.5 Formatter轉換
13.5.6 String.format()
13.6 正則錶達式
13.6.1 基礎
13.6.2 創建正則錶達式
13.6.3 量詞
13.6.4 Pattern和Matcher
13.6.5 split()
13.6.6 替換操作
13.6.7 reset()
13.6.8 正則錶達式與Java I/O
13.7 掃描輸入
13.7.1 Scanner定界符
13.7.2 用正則錶達式掃描
13.8 StringTokenizer
13.9 總結
第14章 類型信息
14.1 為什麼需要RTTI
14.2 Class對象
14.2.1 類字麵常量
14.2.2 泛化的Class引用
14.2.3 新的轉型語法
14.3 類型轉換前先做檢查
14.3.1 使用類字麵常量
14.3.2 動態的instanceof
14.3.3 遞歸計數
14.4 注冊工廠
14.5 instanceof 與 Class的等價性
14.6 反射:運行時的類信息
14.6.1 類方法提取器
14.7 動態代理
14.8 空對象
14.8.1 模擬對象與樁
14.9 接口與類型信息
14.10 總結
第15章 泛型
15.1 與C++的比較
15.2 簡單泛型
15.2.1 一個元組類庫
15.2.2 一個堆棧類
15.2.3 RandomList
15.3 泛型接口
15.4 泛型方法
15.4.1 杠杆利用類型參數推斷
15.4.2 可變參數與泛型方法
15.4.3 用於Generator的泛型方法
15.4.4 一個通用的Generator
15.4.5 簡化元組的使用
15.4.6 一個Set實用工具
15.5 匿名內部類
15.6 構建復雜模型
15.7 擦除的神秘之處
15.7.1 C++的方式
15.7.2 遷移兼容性
15.7.3 擦除的問題
15.7.4 邊界處的動作
15.8 擦除的補償
15.8.1 創建類型實例
15.8.2 泛型數組
15.9 邊界
15.10 通配符
15.10.1 編譯器有多聰明
15.10.2 逆變
15.10.3 無界通配符
15.10.4 捕獲轉換
15.11 問題
15.11.1 任何基本類型都不能作為類型
參數
15.11.2 實現參數化接口
15.11.3 轉型和警告
15.11.4 重載
15.11.5 基類劫持瞭接口
15.12 自限定的類型
15.12.1 古怪的循環泛型
15.12.2 自限定
15.12.3 參數協變
15.13 動態類型安全
15.14 異常
15.15 混型
15.15.1 C++中的混型
15.15.2 與接口混閤
15.15.3 使用裝飾器模式
15.15.4 與動態代理混閤
15.16 潛在類型機製
15.17 對缺乏潛在類型機製的補償
15.17.1 反射
15.17.2 將一個方法應用於序列
15.17.3 當你並未碰巧擁有正確的接口時
15.17.4 用適配器仿真潛在類型機製
15.18 將函數對象用作策略
15.19 總結:轉型真的如此之糟嗎?
15.19.1 進階讀物
第16章 數組
16.1 數組為什麼特殊
16.2 數組是第一級對象
16.3 返迴一個數組
16.4 多維數組
16.5 數組與泛型
16.6 創建測試數據
16.6.1 Arrays.fill()
16.6.2 數據生成器
16.6.3 從Generator中創建數組
16.7 Arrays實用功能
16.7.1 復製數組
16.7.2 數組的比較
16.7.3 數組元素的比較
16.7.4 數組排序
16.7.5 在已排序的數組中查找
16.8 總結
第17章 容器深入研究
17.1 完整的容器分類法
17.2 填充容器
17.2.1 一種Generator解決方案
17.2.2 Map生成器
17.2.3 使用Abstract類
17.3 Collection的功能方法
17.4 可選操作
17.4.1 未獲支持的操作
17.5 List的功能方法
17.6 Set和存儲順序
17.6.1 SortedSet
17.7 隊列
17.7.1 優先級隊列
17.7.2 雙嚮隊列
17.8 理解Map
17.8.1 性能
17.8.2 SortedMap
17.8.3 LinkedHashMap
17.9 散列與散列碼
17.9.1 理解hashCode()
17.9.2 為速度而散列
17.9.3 覆蓋hashCode()
17.10 選擇接口的不同實現
17.10.1 性能測試框架
17.10.2 對List的選擇
17.10.3 微基準測試的危險
17.10.4 對Set的選擇
17.10.5 對Map的選擇
17.11 實用方法
17.11.1 List的排序和查詢
17.11.2 設定Collection或Map為不可
修改
17.11.3 Collection或Map的同步控製
17.12 持有引用
17.12.1 WeakHashMap
17.13 Java 1.0/1.1 的容器
17.13.1 Vector 和 Enumeration
17.13.2 Hashtable
17.13.3 Stack
17.13.4 BitSet
17.14 總結
第18章 Java I/O係統
18.1 File類
18.1.1 目錄列錶器
18.1.2 目錄實用工具
18.1.3 目錄的檢查及創建
18.2 輸入和輸齣
18.2.1 InputStream類型
18.2.2 OutputStream類型
18.3 添加屬性和有用的接口
18.3.1 通過FilterInputStream從InputStream
讀取數據
18.3.2 通過FilterOutPutStream嚮Output-
Stream寫入
18.4 Reader和Writer
18.4.1 數據的來源和去處
18.4.2 更改流的行為
18.4.3 未發生變化的類
18.5 自我獨立的類:RandomAccessFile
18.6 I/O流的典型使用方式
18.6.1 緩衝輸入文件
18.6.2 從內存輸入
18.6.3 格式化的內存輸入
18.6.4 基本的文件輸齣
18.6.5 存儲和恢復數據
18.6.6 讀寫隨機訪問文件
18.6.7 管道流
18.7 文件讀寫的實用工具
18.7.1 讀取二進製文件
18.8 標準I/O
18.8.1 從標準輸入中讀取
18.8.2 將System.out轉換成PrintWriter
18.8.3 標準I/O重定嚮
18.9 進程控製
18.10 新I/O
18.10.1 轉換數據
18.10.2 獲取基本類型
18.10.3 視圖緩衝器
18.10.4 用緩衝器操縱數據
18.10.5 緩衝器的細節
18.10.6 內存映射文件
18.10.7 文件加鎖
18.11 壓縮
18.11.1 用GZIP進行簡單壓縮
18.11.2 用Zip進行多文件保存
18.11.3 Java檔案文件
18.12 對象序列化
18.12.1 尋找類
18.12.2 序列化的控製
18.12.3 使用“持久性”
18.13 XML
18.14 Preferences
18.15 總結
第19章 枚舉類型
19.1 基本enum特性
19.1.1 將靜態導入用於enum
19.2 嚮enum中添加新方法
19.2.1 覆蓋enum的方法
19.3 switch語句中的enum
19.4 values()的神秘之處
19.5 實現,而非繼承
19.6 隨機選取
19.7 使用接口組織枚舉
19.8 使用EnumSet替代標誌
19.9 使用EnumMap
19.10 常量相關的方法
19.10.1 使用enum的職責鏈
19.10.2 使用enum的狀態機
19.11 多路分發
19.11.1 使用enum分發
19.11.2 使用常量相關的方法
19.11.3 使用EnumMap分發
19.11.4 使用二維數組
19.12 總結
第20章 注解
20.1 基本語法
20.1.1 定義注解
20.1.2 元注解
20.2 編寫注解處理器
20.2.1 注解元素
20.2.2 默認值限製
20.2.3 生成外部文件
20.2.4 注解不支持繼承
20.2.5 實現處理器
20.3 使用apt處理注解
20.4 將觀察者模式用於apt
20.5 基於注解的單元測試
20.5.1 將@Unit用於泛型
20.5.2 不需要任何“套件”
20.5.3 實現@Unit
20.5.4 移除測試代碼
20.6 總結
第21章 並發
21.1 並發的多麵性
21.1.1 更快的執行
21.1.2 改進代碼設計
21.2 基本的綫程機製
21.2.1 定義任務
21.2.2 Thread類
21.2.3 使用Executor
21.2.4 從任務中産生返迴值
21.2.5 休眠
21.2.6 優先級
21.2.7 讓步
21.2.8 後颱綫程
21.2.9 編碼的變體
21.2.10 術語
21.2.11 加入一個綫程
21.2.12 創建有響應的用戶界麵
21.2.13 綫程組
21.2.14 捕獲異常
21.3 共享受限資源
21.3.1 不正確地訪問資源
21.3.2 解決共享資源競爭
21.3.3 原子性與易變性
21.3.4 原子類
21.3.5 臨界區
21.3.6 在其他對象上同步
21.3.7 綫程本地存儲
21.4 終結任務
21.4.1 裝飾性花園
21.4.2 在阻塞時終結
21.4.3 中斷
21.4.4 檢查中斷
21.5 綫程之間的協作
21.5.1 wait()與notifyAll()
21.5.2 notify()與notifyAll()
21.5.3 生産者與消費者
21.5.4 生産者-消費者與隊列
21.5.5 任務間使用管道進行輸入/輸齣
21.6 死鎖
21.7 新類庫中的構件
21.7.1 CountDownLatch
21.7.2 CyclicBarrier
21.7.3 DelayQueue
21.7.4 PriorityBlockingQueue
21.7.5 使用ScheduledExecutor的溫室控
製器
21.7.6 Semaphore
21.7.7 Exchanger
21.8 仿真
21.8.1 銀行齣納員仿真
21.8.2 飯店仿真
21.8.3 分發工作
21.9 性能調優
21.9.1 比較各類互斥技術
21.9.2 免鎖容器
21.9.3 樂觀加鎖
21.9.4 ReadWriteLock
21.10 活動對象
21.11 總結
21.12 進階讀物
第22章 圖形化用戶界麵
22.1 applet
22.2 Swing基礎
22.2.1 一個顯示框架
22.3 創建按鈕
22.4 捕獲事件
22.5 文本區域
22.6 控製布局
22.6.1 BorderLayout
22.6.2 FlowLayout
22.6.3 GridLayout
22.6.4 GridBagLayout
22.6.5 絕對定位
22.6.6 BoxLayout
22.6.7 最好的方式是什麼
22.7 Swing事件模型
22.7.1 事件與監聽器的類型
22.7.2 跟蹤多個事件
22.8 Swing組件一覽
22.8.1 按鈕
22.8.2 圖標
22.8.3 工具提示
22.8.4 文本域
22.8.5 邊框
22.8.6 一個迷你編輯器
22.8.7 復選框
22.8.8 單選按鈕
22.8.9 組閤框
22.8.10 列錶框
22.8.11 頁簽麵闆
22.8.12 消息框
22.8.13 菜單
22.8.14 彈齣式菜單
22.8.15 繪圖
22.8.16 對話框
22.8.17 文件對話框
22.8.18 Swing組件上的HTML
22.8.19 滑塊與進度條
22.8.20 選擇外觀
22.8.21 樹、錶格和剪貼闆
22.9 JNLP與Java Web Start
22.10 Swing與並發
22.10.1 長期運行的任務
22.10.2 可視化綫程機製
22.11 可視化編程與JavaBean
22.11.1 JavaBean是什麼
22.11.2 使用Introspector抽取齣BeanInfo
22.11.3 一個更復雜的Bean
22.11.4 JavaBean與同步
22.11.5 把Bean打包
22.11.6 對Bean更高級的支持
22.11.7 有關Bean的其他讀物
22.12 Swing的可替代選擇
22.13 用Flex構建Flash Web客戶端
22.13.1 Hello, Flex
22.13.2 編譯MXML
22.13.3 MXML與ActionScript
22.13.4 容器與控製
22.13.5 效果與樣式
22.13.6 事件
22.13.7 連接到Java
22.13.8 數據模型與數據綁定
22.13.9 構建和部署
22.14 創建SWT應用
22.14.1 安裝SWT
22.14.2 Hello, SWT
22.14.3 根除冗餘代碼
22.14.4 菜單
22.14.5 頁簽麵闆、按鈕和事件
22.14.6 圖形
22.14.7 SWT中的並發
22.14.8 SWT還是Swing
22.15 總結
22.15.1 資源
附錄A 補充材料
附錄B 資源
索引
《自己動手寫JAVA虛擬機》:
前言
第1章 命令行工具
1.1 準備工作
1.1.1 安裝JDK
1.1.2 安裝Go
1.1.3 創建目錄結構
1.2 java命令
1.3 編寫命令行工具
1.4 測試本章代碼
1.5 本章小結
第2章 搜索class文件
2.1 類路徑
2.2 準備工作
2.3 實現類路徑
2.3.1 Entry接口
2.3.2 DirEntry
2.3.3 ZipEntry
2.3.4 CompositeEntry
2.3.5 WildcardEntry
2.3.6 Classpath
2.4 測試本章代碼
2.5 本章小結
第3章 解析class文件
3.1 class文件
3.2 解析class文件
3.2.1 讀取數據
3.2.2 整體結構
3.2.3 魔數
3.2.4 版本號
3.2.5 類訪問標誌
3.2.6 類和超類索引
3.2.7 接口索引錶
3.2.8 字段和方法錶
3.3 解析常量池
3.3.1 ConstantPool結構體
3.3.2 ConstantInfo接口
3.3.3 CONSTANT_Integer_info
3.3.4 CONSTANT_Float_info
3.3.5 CONSTANT_Long_info
3.3.6 CONSTANT_Double_info
3.3.7 CONSTANT_Utf8_info
3.3.8 CONSTANT_String_info
……
第4章 運行時數據區
第5章 指令集和解釋器
第6章 類和對象
第7章 方法調用和返迴
第8章 數組和字符串
第9章 本地方法調用
第10章 異常處理
第11章 結束
附錄 指令錶
前言/序言
時隔兩年多,《Java編程思想(第4版)》的中文版又要和廣大Java程序員和愛好者們見麵瞭。這是Java語言本身不斷發展和完善的必然要求,也是本書作者BruceEckel孜孜不倦的創作激情和靈感所結齣的碩果。《Java編程思想(第4版)》以Java最新的版本JDK5.0為基礎,在第3版的基礎上,添加瞭最新的語言特性,並且對第3版的結構進行瞭調整,使得所有章節的安排更加遵照循序漸進的特點,同時每一章的內容在分量上也都更加均衡,這使讀者能夠更加容易地閱讀本書並充分瞭解每章所講述的內容。在這裏我們再次嚮BruceEckel緻敬,他不但嚮我們展示瞭什麼樣的書籍纔是經典書籍,而且還展示瞭經典書籍怎樣纔能精益求精,長盛不衰。
Java已經成為瞭編程語言的驕子。我們可以看到,越來越多的大學在教授數據結構、程序設計和算法分析等課程時,選擇以Java語言為載體。這說明Java語言已經是人們構建軟件係統時主要使用的一種編程語言。但是,掌握好Java語言並不是一件可以輕鬆完成的任務,如何真正掌握Java語言,從而編寫齣健壯的、高效的以及靈活的程序是Java程序員們麵臨的重大挑戰。《Java編程思想(第4版)》就是一本能夠讓Java程序員輕鬆麵對這一挑戰,並最終取得勝利的經典書籍。本書深入淺齣、循序漸進地把我們領入Java的世界,讓我們在不知不覺中就學會瞭用Java的思想去考慮問題、解決問題。本書不僅適閤Java的初學者,更適閤乾有經驗的Java程序員,這正是本書的魅力所在。但是,書中並沒有涵蓋Java所有的類、接口和方法,因此,如果你希望將它當作Java的字典來使用,那麼顯然就要失望瞭。
我們在翻譯本書的過程中力求忠於原著,為瞭保持連貫性,對原書第3版中仍然保持不變的部分,我們對譯文除瞭個彆地方之外,也沒做修改。對於本書中齣現的大量的專業術語盡量遵循標準的譯法,並在有可能引起歧義之處注有英文原文,以方便讀者對照與理解。
全書由陳昊鵬翻譯,郭嘉也參與瞭部分翻譯工作。由於水平有限,書中齣現錯誤與不妥之處在所難免,懇請讀者批評指正。
深度探索Java虛擬機:從原理到實戰的高階指南 前言 在浩瀚的計算機科學領域,Java虛擬機(JVM)無疑是最為關鍵的存在之一。它不僅是Java語言執行的基石,更是理解Java高性能、跨平颱特性的核心。本書旨在引領讀者深入JVM的內部世界,從理論到實踐,一步步揭開虛擬機運作的神秘麵紗。我們相信,唯有深刻理解JVM,纔能真正掌握Java的精髓,編寫齣更高效、更健壯的代碼,甚至在特定領域進行創新性的開發。 第一冊:JVM核心原理剖析 第一章:Java虛擬機概覽與架構 1.1 虛擬機的重要性與曆史演進: 探討虛擬機的概念,以及JVM在Java生態係統中的核心地位。迴顧JVM的發展曆程,從JDK 1.0到最新的JDK版本,瞭解其在性能優化、垃圾迴收、並發處理等方麵的演進。 1.2 JVM的邏輯架構: 詳細解析JVM的整體架構,包括類文件(.class)的加載、驗證、準備、解析和初始化過程。介紹JVM運行時數據區,包括程序計數器、Java堆、方法區(元空間)、棧(Java虛擬機棧、本地方法棧)以及它們各自的功能與生命周期。 1.3 字節碼:JVM的中間語言: 深入理解Java源代碼如何被編譯成字節碼(Bytecode),以及字節碼的特性和優勢。通過實例展示常見的字節碼指令,為後續的深入分析打下基礎。 1.4 JVM與操作係統的交互: 闡述JVM如何與底層操作係統進行交互,包括內存管理、綫程調度、I/O操作等。理解JVM如何屏蔽底層硬件和操作係統的差異,實現Java的跨平颱性。 第二章:類加載機製詳解 2.1 類加載器的概念與作用: 詳細介紹JVM提供的三種內置類加載器:根類加載器(Bootstrap ClassLoader)、擴展類加載器(Extension ClassLoader)和應用程序類加載器(Application ClassLoader)。解釋它們之間的父子關係和委派機製。 2.2 雙親委派模型: 深入理解雙親委派模型的工作原理,分析其優勢,如保證類的唯一性、防止惡意代碼篡改等。通過源碼分析和調試,加深對該模型的理解。 2.3 自定義類加載器: 講解如何編寫自定義類加載器,以及在何種場景下需要使用自定義類加載器(如熱部署、加密class文件等)。通過實際案例演示自定義類加載器的實現。 2.4 類加載過程:加載、鏈接(驗證、準備、解析)、初始化: 分步詳解類加載的三個重要階段。重點關注鏈接階段的驗證(保證class文件的安全性)、準備(為靜態變量分配內存並初始化為默認值)和解析(將符號引用轉換為直接引用)。深入分析初始化階段的執行順序和觸發時機。 第三章:JVM內存模型與垃圾迴收(一):內存區域劃分與對象分配 3.1 Java堆:對象的傢園: 詳細分析Java堆的組成部分:新生代(Eden區、From Survivor區、To Survivor區)和老年代。講解對象的分配過程,包括在Eden區的創建、Minor GC、對象的晉升機製。 3.2 對象分配原則: 深入理解各種對象分配原則,如大對象直接進入老年代、長期存活對象進入老年代、TLAB(Thread Local Allocation Buffer)的使用等。 3.3 方法區(元空間): 講解方法區的演變,從永久代到元空間的遷移。分析方法區存儲的信息,如類信息、常量池、字段和方法數據、方法體的字節碼等。 3.4 棧:局部變量與方法調用的舞颱: 詳細分析Java虛擬機棧(Java Stack)和本地方法棧(Native Method Stack),包括棧幀(Stack Frame)的結構(局部變量錶、操作數棧、動態鏈接、方法齣口等)以及方法調用和返迴的過程。 3.5 程序計數器:綫程的指揮棒: 講解程序計數器的作用,用於指示當前綫程執行的字節碼指令地址。 第四章:JVM內存模型與垃圾迴收(二):垃圾迴收算法與垃圾收集器 4.1 垃圾迴收(GC)的基本概念: 講解GC的必要性,以及GC的兩個核心問題:判斷對象是否存活、如何迴收對象。 4.2 垃圾迴收算法: 詳細介紹多種經典的GC算法: 標記-清除(Mark-Sweep): 原理、優缺點(産生內存碎片)。 標記-整理(Mark-Compact): 改進標記-清除,解決碎片問題。 復製(Copying): 原理、適用於新生代,優點(無碎片),缺點(浪費空間)。 分代收集理論: 解釋為何采用分代收集,以及各代(新生代、老年代)的特點和適用的GC算法。 4.3 常見的垃圾收集器: 深入分析JVM中各種經典的垃圾收集器,包括它們的特點、適用場景、工作原理及性能指標: Serial GC: 簡單、單綫程,適用於客戶端和單核CPU。 ParNew GC: Serial GC的多綫程版本。 Parallel Scavenge GC: 關注吞吐量,適用於需要高吞吐量的場景。 CMS GC(Concurrent Mark Sweep): 關注延遲,適用於需要低延遲的Web應用。 G1 GC(Garbage-First): 區域化並行、並發,適用於大內存、多核CPU,是目前主流的收集器。 ZGC & Shenandoah GC: 關注極低延遲(亞毫秒級),適用於對延遲極其敏感的應用。 4.4 GC日誌分析: 學習如何通過GC日誌來監控JVM的內存使用情況、GC的頻率和耗時,以及如何根據GC日誌診斷性能問題。 第五章:JVM性能調優與監控 5.1 性能調優的目標與原則: 明確JVM性能調優的目標(提升吞吐量、降低延遲、減少內存占用等)和基本原則。 5.2 常見的性能瓶頸與排查: 分析CPU、內存、I/O等方麵的常見性能瓶頸,以及如何使用工具進行排查。 5.3 JVM參數調優: 詳解JVM常用調優參數,包括內存相關的參數(-Xms, -Xmx, -XX:NewRatio等)、GC相關的參數(-XX:+UseG1GC, -XX:MaxGCPauseMillis等)、綫程相關的參數以及其他常用參數。 5.4 性能監控工具: 介紹和使用各種JVM性能監控工具,包括: JDK自帶工具: `jps`, `jstat`, `jmap`, `jstack`, `jcmd`等。 第三方工具: VisualVM, JConsole, MAT (Eclipse Memory Analyzer Tool), YourKit, JProfiler等。 5.5 實際案例分析: 通過實際項目中的性能問題,演示如何應用所學知識進行問題診斷和性能優化。 第二冊:動手實踐與源碼探索 第六章:理解字節碼與字節碼增強 6.1}. Class文件結構剖析: 深入研究.class文件的二進製結構,包括魔數、版本號、常量池、訪問標誌、字段、方法等。學習使用`javap`命令來反編譯class文件。 6.2}. 字節碼指令集詳解: 詳細解讀JVM的字節碼指令集,理解各種指令的功能,如加載/存儲指令、算術指令、對象操作指令、控製轉移指令、方法調用指令等。 6.3}. 字節碼增強技術(ASM/Byte Buddy): 介紹字節碼增強(Bytecode Enhancement)的概念,以及常見的字節碼增強框架,如ASM和Byte Buddy。 ASM基礎: 學習如何使用ASM API來讀取、修改和生成字節碼。通過實際示例演示如何修改已有的class文件,例如添加日誌打印、修改方法返迴值等。 Byte Buddy入門: 介紹Byte Buddy的簡潔API,如何更方便地進行字節碼生成和增強。 6.4}. 動態代理與字節碼增強: 結閤動態代理的原理,理解字節碼增強在動態代理實現中的應用。 第七章:動手構建簡易JVM(模擬核心功能) 7.1}. JVM架構模擬: 設計和實現一個簡易的JVM模擬器,涵蓋核心的組件,如類加載器、指令解釋器、內存區域(簡化的堆和棧)。 7.2}. 字節碼解釋器實現: 實現一個基於棧的字節碼解釋器,能夠解析和執行部分Java字節碼指令。 7.3}. 簡單的內存管理與垃圾迴收模擬: 實現一個最基礎的內存分配和迴收機製,例如簡單的標記-清除算法,用於模擬對象在堆中的創建和釋放。 7.4}. 方法調用與棧幀模擬: 實現方法調用和棧幀的管理,模擬Java方法執行的過程。 7.5}. 限製與擴展: 討論在模擬器中實現更復雜功能的挑戰,以及可能的擴展方嚮(如支持更多指令、更復雜的GC算法等)。 第八章:深入理解Java內存模型(JMM)與並發編程 8.1}. JMM的核心概念: 詳細闡述Java內存模型,包括主內存、工作內存、原子性、可見性、有序性。 8.2}. 指令重排: 深入理解JVM和CPU的指令重排機製,以及其可能帶來的並發問題。 8.3}. JMM的內存可見性保證: 講解`volatile`關鍵字的作用,如何實現內存可見性。 8.4}. Java並發關鍵字與工具: `synchronized`關鍵字: 講解鎖的機製,包括對象鎖和類鎖,以及`synchronized`在不同場景下的應用。 `Lock`接口與`ReentrantLock`: 學習使用更靈活的JUC鎖。 `java.util.concurrent`包: 介紹`ExecutorService`、`ThreadPoolExecutor`、`Future`、`Callable`、`Semaphore`、`CountDownLatch`、`CyclicBarrier`等常用的並發工具類。 8.5}. 綫程安全問題與解決方案: 分析常見的綫程安全問題,如競態條件、死鎖、活鎖等,並給齣相應的解決方案。 第九章:JVM的即時編譯(JIT)與性能優化 9.1}. JIT編譯器的作用與原理: 介紹JIT(Just-In-Time)編譯器的概念,以及它如何將熱點代碼(HotSpot Code)從字節碼編譯成本地機器碼,從而提高程序執行效率。 9.2}. C1(Client)和C2(Server)編譯器: 詳細對比C1和C2編譯器的特點、優化級彆和適用場景。 9.3}. 熱點代碼探測: 講解JVM如何通過采樣統計(Sampling)或計數統計(Counting)來識彆熱點代碼。 9.4}. JIT編譯器的優化技術: 介紹JIT編譯器常用的優化手段,如方法內聯(Inlining)、逃逸分析(Escape Analysis)、死代碼消除(Dead Code Elimination)等。 9.5}. 瞭解JVM的執行流程: 結閤解釋執行和JIT編譯,全麵理解Java程序的執行流程。 第十章:高級主題與實踐 10.1}. JVM垃圾迴收調優進階: 深入分析特定場景下的GC調優策略,如大內存應用的GC調優、高並發請求的GC調優。 10.2}. JVM類加載機製的深入應用: 探討Java Agent、Java Instrumentation等高級類加載機製的應用,如監控、調試、代碼注入等。 10.3}. 剖析JVM內部實現: 引導讀者在具備一定基礎後,可以進一步閱讀JVM的開源實現(如OpenJDK)的源碼,加深對JVM內部設計的理解。 10.4}. JVM中的其他高級特性: 簡要介紹JVM的一些其他高級特性,如類文件格式的演變、invokedynamic指令、模塊化(Project Jigsaw)等。 10.5}. 虛擬機發展趨勢與未來展望: 探討JVM未來的發展方嚮,如GraalVM、WebAssembly等,以及它們對Java生態的影響。 結語 掌握Java虛擬機,就像獲得瞭一把解鎖Java語言強大潛力的金鑰匙。本書從理論基礎到實踐操作,旨在為讀者構建一個全麵而深入的JVM認知體係。我們鼓勵讀者在閱讀過程中,勤於思考,勇於實踐,利用各種工具進行探索和驗證。願本書能成為您在Java虛擬機領域求知路上的有力夥伴,助您成為一名真正精通Java的開發者。