JDK 5(代號「Tiger」,老虎)以「簡化開發」為核心主題,引入六大語言級特性,從根本上改變了 Java 代碼風格,使代碼更清晰、更安全、更具表達力。本文逐一深度解析並給出實戰建議。
// JDK 1.4:集合無類型約束,取出需強轉,運行時才暴露錯誤
List list = new ArrayList();
list.add("hello");
list.add(new Date()); // 編譯通過,隱患埋下
String s = (String) list.get(1); // ClassCastException
// JDK 5:編譯期強制類型檢查
List list = new ArrayList();
list.add("hello");
list.add(new Date()); // 編譯錯誤:add(Date) not applicable for (String)
String s = list.get(0); // 無需強轉
ClassCastException 風險。Map> 即說明結構。// 上界:只能讀取 T 或其子類,不能寫入(除 null)
void process(List extends Number> nums) { ... }
// 下界:只能寫入 T 或其父類,讀取只能作 Object
void addIntegers(List super Integer> list) { list.add(1); }
// 無界:等同於 extends Object>,只能讀取 Object
void printAll(List> list) { ... }
// 舊式迭代器
for (Iterator it = c.iterator(); it.hasNext(); ) {
MyClass obj = (MyClass) it.next();
obj.process();
}
// 增強 for:乾淨、無索引錯誤、自動類型推導
for (MyClass obj : c) {
obj.process();
}
// 也適用於數組
int[] arr = {1,2,3};
for (int n : arr) System.out.println(n);
限制:無法獲取索引、無法反向遍歷、無法在循環中移除元素(需用 Iterator)。
Integer i = 10; // 自動裝箱:int → Integer
int n = i; // 自動拆箱:Integer → int
List list = new ArrayList<>();
list.add(3); // 3 自動裝箱為 Integer
int sum = list.get(0) + list.get(1); // 自動拆箱相加,結果再裝箱存入
Long sum = 0L; for (...) sum += i; 每次循環創建新 Long → 改用基本類型 long sum = 0L;。Integer i = null; int n = i; → 運行時 NullPointerException,難以排查。Integer.valueOf() 緩存 -128~127,超出範圍每次新建對象,影響 == 比較語義。public enum Color {
RED("紅色", 0xFF0000),
GREEN("綠色", 0x00FF00),
BLUE("藍色", 0x0000FF);
private final String name;
private final int rgb;
Color(String name, int rgb) { this.name = name; this.rgb = rgb; }
public String getName() { return name; }
public int getRgb() { return rgb; }
}
// 使用
Color c = Color.RED;
switch (c) {
case RED: ...; break;
case GREEN: ...; break;
}
// 內置方法
for (Color col : Color.values()) System.out.println(col.name() + "=" + col.ordinal());
Color c2 = Color.valueOf("RED"); // 字符串轉枚舉,區分大小寫
public enum Singleton {
INSTANCE;
public void doSomething() { ... }
}
// 線程安全、防反射破壞、防序列化重建
// 以前:需重載或傳數組
void print(String... msgs) {
for (String m : msgs) System.out.println(m);
}
print("A");
print("A", "B");
print("A", "B", "C");
print(new String[]{"A","B"}); // 也可傳數組
method.invoke(obj, args) 可直接傳可變參數陣列。import static java.lang.Math.*;
import static java.util.Collections.*;
double r = sin(PI * 2); // 無需 Math.sin, Math.PI
List list = emptyList(); // 無需 Collections.emptyList()
Math.PI)或工廠方法(如 Collections.emptyList()),避免導入大量方法。| 特性 | 核心收益 | 遷移優先級 | 風險提示 |
|---|---|---|---|
| 泛型 | 類型安全、消除強轉 | 最高 | 擦除機制導致運行期類型信息缺失 |
| 增強 for | 代碼簡潔、減少索引錯誤 | 高 | 不可移除元素、無索引 |
| 自動裝箱 | 基本類型進集合無障礙 | 高 | 性能、NPE、緩存陷阱 |
| 枚舉 | 類型安全常量、單例最佳實踐 | 高 | 無 |
| 可變參數 | 簡化重載、API 靈活 | 中 | 數組創建開銷、歧義調用 |
| 靜態導入 | 代碼簡潔 | 低 | 命名衝突、可讀性下降 |
JDK 5 的六大特性相輔相成,共同推動 Java 向更表達力、更安全、更現代的方向演進。掌握其精髓與避坑指南,是寫出高質量 Java 代碼的必修課。