前言:從語法規則到工程思維的轉折
Java 基礎語法入門後,異常處理、面向對象核心機制、集合框架是通往專業開發的三座大山。本文以問答形式,系統梳理 31 條核心知識點,直擊易混淆易踩坑要害。
一、異常處理機制 (31-33)
31. throw vs throws:拋出 vs 聲明
- throws:方法簽名聲明**可能拋出**的受檢異常,給調用者契約承諾
- throw:方法體內**實際拋出**異常實例的動作
- 受檢異常 (Checked Exception) 必須 `throws` 或 `try-catch` 處理,否則編譯錯誤
- 例外:`Error`、`RuntimeException` 及其子類為非受檢異常,無須聲明
32. 異常本質與標準捕獲範式
- 起源:Ada 語言引入,動態處理錯誤並恢復
- 核心價值:將錯誤處理與業務邏輯分離,支援跨層傳播
try {
// 高風險操作
} catch (SpecificException1 e) { // 子類異常優先捕獲
// 處理特定情況
} catch (SpecificException2 e) {
// 處理另一情況
} catch (Exception e) { // 父類異常兜底
// 通用處理/記錄/轉換
} finally {
// 無論是否異常必執行:資源釋放、鎖釋放、連線關閉
}
33. final vs finally:修飾符 vs 異常區塊
- `final`:修飾類(不可繼承)、方法(不可覆寫)、變數(不可重賦值/引用不變)
- `finally`:異常處理區塊,保證執行清理邏輯
二、面向對象核心機制 (34-47)
34. extends vs implements:繼承 vs 實作
- `extends`:單繼承類 (含抽象類),獲得實作複用
- `implements`:實作介面 (可多實作),履行契約承諾
- 介面引入目的:部分實現多重繼承功能,避免 C++ 菱形繼承難題
35. Java 如何實現多重繼承?
- **不支援**類的顯式多重繼承 (避免構造函數鏈混亂、封裝性破壞)
- 通過「實作多個介面」+「組合/委派」實現多型複用
- 介面間可 `extends` 構建契約層次
36. abstract 抽象類/方法
- 抽象方法:無方法體,強制子類實作
- 含抽象方法的類必須宣告 `abstract`
- 抽象類不可實例化,但可有建構子 (供子類 `super()` 調用)
- 抽象類 = 部分實作 + 部分契約,介面 = 純契約
37. 存取修飾符四大可見性
| 修飾符 | 同類 | 同包 | 子類 | 任意處 |
| private | ✓ | ✗ | ✗ | ✗ |
| default (包私有) | ✓ | ✓ | ✗ | ✗ |
| protected | ✓ | ✓ | ✓ | ✗ |
| public | ✓ | ✓ | ✓ | ✓ |
- 類只能 `public` 或 `default`
- `protected` 核心意圖:開放給子類 (含跨包),而非包內類
38. Override vs Overload:覆寫 vs 多載
| 維度 | Override (覆寫) | Overload (多載) |
| 發生範圍 | 父子類之間 | 同一類內 (含繼承體系) |
| 方法簽名 | 相同 (名稱、參數表) | 名稱相同、參數表不同 |
| 返回類型 | 兼容 (JDK 5+ 共變返回) | 可異 |
| 拋出異常 | 不可拋出更寬泛受檢異常 | 無限制 |
| 核心目的 | 多態、擴展行為 | 便利調用、語義分組 |
39-41. super / this 在建構子與方法中的用法
- 調用父類方法:`super.method()` (覆寫時保留父類邏輯)
- 調用父類建構子:子類建構子**第一行** `super(args)`
- 調用本類其他建構子:建構子**第一行** `this(args)`
- 鏈式調用最終必達 `Object()` 無參建構子
42-43. 建構子預設規則
- 無任何建構子 → 編譯器自動生成 `public ClassName() {}`
- 自定義任一建構子 → **不再**自動生成無參建構子,需顯式提供
44. finalize():最終化而非解構子
- GC 回收前調用,非確定性、非即時、可能永不執行
- **不建議**依賴釋放資源 (用 `try-with-resources` / `AutoCloseable`)
- 已在 JDK 9 標記棄用,JDK 18 移除
45-46. 向下轉型與 instanceof 守護
- 父類引用指向子類物件時,可 `(SubType) ref` 強轉
- 錯誤轉型拋 `ClassCastException`
- 安全模式:`if (ref instanceof SubType) { SubType s = (SubType) ref; }`
- JDK 16+ 模式匹配:`if (ref instanceof SubType s) { s.method(); }`
47. 參數傳遞陷阱:引用傳值的誤區
// 錯誤示範:重新賦值參數變數,斷開與外部物件關聯
public void broken(Foo foo) {
foo = new Foo(); // 參數變數指向新物件
foo.setAttr(value); // 修改新物件,外部原物件未變
}
// 正確:修改物件內部狀態
public void correct(Foo foo) {
foo.setAttr(value); // 修改同一物件狀態
}
// 基本型別同理:參數是副本,修改不影響外部
public void primitive(int x) { x = 10; } // 外部變數不變
三、集合框架精要 (48-61)
48-49. 陣列基礎
- 動態分配:`int n = 3; Language[] arr = new Language[n];`
- 長度屬性:`arr.length` (非方法,不可變)
50-51. List:有序、可重複、動態陣列
- 介面:`java.util.List`
- 實作:`ArrayList` (陣列、隨機存取快) / `LinkedList` (鏈表、首尾增刪快)
- 選擇原則:預設 `ArrayList`,頻繁頭尾操作用 `LinkedList`
52. Queue/Stack:雙端隊列/棧
- `Deque` 介面、`LinkedList` 實作同時支援隊列 (FIFO) 與棧 (LIFO)
- 棧操作:`push()`/`pop()`/`peek()`;隊列:`offer()`/`poll()`/`peek()`
- 避免使用舊 `Stack` 類 (繼承 `Vector`、同步開銷大)
53. Set:無序、唯一
- 介面:`Set`,實作:`HashSet` (雜湊、O(1)) / `TreeSet` (紅黑樹、有序、O(log n))
- 元素需正確實作 `equals()` + `hashCode()` (HashSet) / `Comparable` (TreeSet)
54. Iterator:統一遍歷抽象
- `iterator()` 返回 `Iterator`,`hasNext()`/`next()`/`remove()`
- 支援 `for-each` 隱式迭代:`for (E e : collection)`
- Map 遍歷:`entrySet()` / `keySet()` / `values()`
55. TreeSet:自動排序
- 元素實作 `Comparable` (自然序) 或建構傳入 `Comparator` (定製序)
- 需一致性:`compareTo` 返回 0 ⇔ `equals` 返回 true
56-57. 陣列/集合排序
- `Arrays.sort(array)` / `Collections.sort(list)`
- 多準則排序:實作多個 `Comparator`,配合 `Arrays.sort(arr, comparator)`
58-59. Map:鍵值映射
- 介面:`Map`,主流:`HashMap` (雜湊)、`TreeMap` (有序)、`LinkedHashMap` (插入序)
- `get()` 返回 `Object` (舊版) 或泛型值 (JDK 5+),需強轉或用泛型聲明
60. Random:偽隨機數
- `new Random().nextInt(bound)` / `nextDouble()` / `nextGaussian()`
- 安全需求用 `SecureRandom`
61. 字串比較鐵律
- **絕對禁止** `==` 比較字串內容 (比較引用地址)
- 必須用 `equals()` (區分大小寫) / `equalsIgnoreCase()` (忽略大小寫)
- 字串常量池導致 `==` 有時成立 (編譯期常量),產生幻覺
總結
異常體系建立「失敗可控」的契約;面向對象機制確立「封裝、繼承、多態」三大支柱;集合框架提供「演算法與資料結構分離」的標準庫。掌握這 31 條知識點的**語義邊界**與**工程陷阱**,能讓開發者寫出更健壯、更符合慣用語、更易維護的 Java 代碼。下一階段建議深入:泛型擦除機制、併發集合、Stream API 函數式操作、模組系統 (JPMS)。