首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> J2SE

J2SE 5.0 (Tiger) 新特性實戰速成:泛型、註解、枚舉、可變參數、格式化輸出與增強 for 循環

     編輯:J2SE

前言:Tiger —— 讓 Java 語法更表達力、更類型安全、更工程化

JDK 5.0 (代號 Tiger) 是 Java 語言發展史上里程碑式版本,引入泛型、註解、枚舉、自動拆裝箱、可變參數、增強 for 循環、靜態導入、格式化輸出等特性,徹底改變了 Java 代碼風格。本文通過可運行示例,系統演示核心新特性語法、編譯/運行命令、常見陷阱與最佳實踐。

一、 泛型 —— 編譯期類型安全,擦除後無痕

1.1 基本語法與類型推導

// 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); }

1.2 自定義泛型類/方法

// 泛型類
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) { ... }

1.3 通配符與 PECS 原則


// 生產者用 extends (讀取) - Producer Extends
void printAll(List nums) { for (Number n : nums) System.out.println(n); }

// 消費者用 super (寫入) - Consumer Super
void addIntegers(List list) { list.add(1); list.add(2); }

// 無限制通配符 (相當於 ? extends Object)
void printRaw(List list) { for (Object o : list) System.out.println(o); }

1.4 類型擦除與陷阱

  • 運行時泛型信息被擦除:List 和 List 都是 List。
  • 不能 new T()、T[]、instanceof T、靜態欄位用 T。
  • 橋接方法自動生成保證多態。
  • 堆污染:List ls = new ArrayList<>(); List raw = ls; raw.add(123); // 編譯警告,運行時 ClassCastException。

二、 註解 —— 元數據編程,從文檔到編譯器插件

2.1 內建標準註解

@Override       // 檢查是否正確重寫父類方法,防止拼寫錯誤
@Deprecated     // 標記過時,編譯器警告
@SuppressWarnings("unchecked") // 抑制特定警告
@SafeVarargs    // 聲明可變參數方法類型安全 (JDK 7+)
@FunctionalInterface // 聲明函數式接口 (JDK 8+)

2.2 元註解:定義註解的註解

@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 {};     // 數組屬性
}

2.3 運行時反射讀取註解

@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) 否則反射獲取不到。

三、 枚舉 —— 類型安全的常量集合,支持行為豐富

3.1 基本定義與用法

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); }
}

3.2 EnumMap / EnumSet —— 高性能專用集合

// 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);

四、 可變參數 —— 簡化數組創建,配合格式化輸出威力倍增

4.1 語法與本質

// 定義:類型... 參數名 (只能出現在參數列表最後)
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)

4.2 格式化輸出 System.out.printf / String.format

// 格式化語法: %[參數索引$][標誌][寬度][.精度]轉換符
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 循環 —— 統一遍歷語法,背後是 Iterable

5.1 支持類型

  • 數組:for (int i : intArray)
  • Iterable 實現:Collection、Set、List、自定義類實現 Iterable

5.2 自定義可遍歷類

class 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

5.3 限制與注意

  • 無法獲取索引 (需手工計數或用傳統 for)。
  • 無法在循環中移除元素 (需用 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 代碼。建議在現有專案中漸進式遷移:新代碼全面使用泛型/註解/枚舉,舊代碼重構時引入。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved