JDK 5.0 (代號 Tiger) 是 Java 語言發展史上里程碑式版本,引入泛型、註解、枚舉、自動拆裝箱、可變參數、增強 for 循環、靜態導入、格式化輸出等特性,徹底改變了 Java 代碼風格。本文通過可運行示例,系統演示核心新特性語法、編譯/運行命令、常見陷阱與最佳實踐。
// JDK 5 原始寫法 (顯式類型參數)
List list = new ArrayList();
list.add("hello");
// list.add(123); // 編譯錯誤:類型不匹配
// JDK 7+ 鑽石語法
List list = new ArrayList<>();
// 遍歷:增強 for + 泛型 = 無需轉型
for (String s : list) { System.out.println(s); }
// 泛型類
class Box {
private T value;
public void set(T v) { value = v; }
public T get() { return value; }
}
// 泛型方法 (類型參數在返回類型前)
public static void swap(List list, int i, int j) {
T tmp = list.get(i); list.set(i, list.get(j)); list.set(j, tmp);
}
// 限定類型參數上界
public static > T max(Collection coll) { ... }
// 生產者用 extends (讀取) - Producer Extends
void printAll(List extends Number> nums) { for (Number n : nums) System.out.println(n); }
// 消費者用 super (寫入) - Consumer Super
void addIntegers(List super Integer> list) { list.add(1); list.add(2); }
// 無限制通配符 (相當於 ? extends Object)
void printRaw(List> list) { for (Object o : list) System.out.println(o); }
List 和 List 都是 List。new T()、T[]、instanceof T、靜態欄位用 T。List ls = new ArrayList<>(); List raw = ls; raw.add(123); // 編譯警告,運行時 ClassCastException。 @Override // 檢查是否正確重寫父類方法,防止拼寫錯誤
@Deprecated // 標記過時,編譯器警告
@SuppressWarnings("unchecked") // 抑制特定警告
@SafeVarargs // 聲明可變參數方法類型安全 (JDK 7+)
@FunctionalInterface // 聲明函數式接口 (JDK 8+)
@Retention(RetentionPolicy.RUNTIME) // 保留策略:SOURCE < CLASS < RUNTIME
@Target(ElementType.METHOD) // 作用目標:TYPE, FIELD, METHOD, PARAMETER, CONSTRUCTOR, LOCAL_VARIABLE, ANNOTATION_TYPE, PACKAGE, TYPE_PARAMETER, TYPE_USE (JDK 8+)
@Documented // 納入 Javadoc
@Inherited // 子類繼承父類註解 (僅針對 TYPE)
@interface MyAnnotation {
String value() default ""; // 默認值
int count() default 0;
String[] tags() default {}; // 數組屬性
}
@MyAnnotation(value="test", count=1, tags={"a","b"})
public void annotatedMethod() {}
public static void main(String[] args) throws Exception {
Method m = Main.class.getMethod("annotatedMethod");
MyAnnotation ann = m.getAnnotation(MyAnnotation.class);
System.out.println(ann.value()); // "test"
System.out.println(ann.count()); // 1
System.out.println(Arrays.toString(ann.tags())); // [a, b]
}
關鍵:@Retention(RUNTIME) 否則反射獲取不到。
enum Season { SPRING, SUMMER, AUTUMN, WINTER }
Season s = Season.SPRING;
switch (s) {
case SPRING: System.out.println("春"); break;
// 無需 default,編譯器檢查覆蓋率 (JDK 7+)
}
for (Season season : Season.values()) { // 獲取所有常量
System.out.println(season + " ordinal=" + season.ordinal());
}
// 枚舉實現接口、擁有字段方法
enum Color implements Runnable {
RED(0xFF0000), GREEN(0x00FF00), BLUE(0x0000FF);
private final int rgb;
Color(int rgb) { this.rgb = rgb; }
public int getRgb() { return rgb; }
@Override public void run() { System.out.println("Color: " + this); }
}
// EnumMap: key 為枚舉,內部用數組,極快、無裝箱
EnumMap activities = new EnumMap<>(Season.class);
activities.put(Season.SPRING, "踏青");
activities.put(Season.SUMMER, "游泳");
// EnumSet: 位向量實現,極緊湊、極快
EnumSet summerWinter = EnumSet.of(Season.SUMMER, Season.WINTER);
EnumSet all = EnumSet.allOf(Season.class);
// 定義:類型... 參數名 (只能出現在參數列表最後)
public static void printf(String format, Object... args) { ... }
// 調用:傳多個參數 或 陣列
printf("Hello %s, %s!", "World", "Java"); // 自動包裝為 Object[]
printf("Numbers: %d, %d", 1, 2); // 自動裝箱
// 內部接收為 Object[] args,注意:
// 1. 傳 null → args 為 null (非長度 0 數組)
// 2. 傳陣列 → 直接接收,不再包裝
Object[] arr = {"a", "b"};
printf("%s %s", arr); // 等價 printf("%s %s", (Object[]) arr)
// 格式化語法: %[參數索引$][標誌][寬度][.精度]轉換符
System.out.printf("PI = %10.5f%n", Math.PI); // 寬度 10, 精度 5, 右對齊
System.out.printf("Name: %-10s Age: %3d%n", "Tom", 20); // 左對齊 - 標誌
System.out.printf("Hex: %08X%n", 255); // 0 補齊 8 位大寫十六進制
System.out.printf("%,d%n", 1234567); // 分組分隔符 (區域相關)
// String.format 返回格式化字符串
String msg = String.format("User %s logged in at %tF %
for (int i : intArray)Iterable 實現:Collection、Set、List、自定義類實現 Iterableclass TenNumbers implements Iterable {
@Override public Iterator iterator() {
return new Iterator<>() {
int n = 0;
public boolean hasNext() { return n < 10; }
public Integer next() { return n++; }
};
}
}
for (Integer i : new TenNumbers()) { System.out.println(i); } // 0..9
Iterator.remove() 或 ListIterator)。Iterator 模式。public final class Log {
private Log() {}
// 可變參數 + 格式化 + 枚舉級別
public enum Level { DEBUG, INFO, WARN, ERROR }
private static final DateTimeFormatter FMT = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss.SSS");
public static void log(Level level, String format, Object... args) {
String msg = String.format(format, args);
String line = String.format("[%s] [%s] %s",
LocalDateTime.now().format(FMT), level.name(), msg);
System.out.println(line);
// 實際可接入 SLF4J/Log4j2
}
// 便利方法
public static void info(String fmt, Object... args) { log(Level.INFO, fmt, args); }
public static void error(String fmt, Object... args) { log(Level.ERROR, fmt, args); }
}
// 使用
Log.info("User %s login from %s", username, ip);
Log.error("DB connection failed: %s", e.getMessage());
Tiger 的新特性不僅是語法糖,更是類型系統增強 (泛型)、元數據標準化 (註解)、領域建模能力提升 (枚舉)、表達力躍升 (可變參數/格式化/增強 for)的綜合體現。熟練掌握它們,能寫出更安全、更易讀、更可維護的 Java 代碼。建議在現有專案中漸進式遷移:新代碼全面使用泛型/註解/枚舉,舊代碼重構時引入。