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

J2SE 1.5 Tiger 新特性實戰(一):自訂泛型類與型別擦除示範

     編輯:J2SE

前言

J2SE 1.5 泛型的核心在於「參數化類型」。本文從最簡單的自訂泛型類入手,展示型別參數宣告、具體化實例化、型別安全保障,以及著名的「型別擦除」導致的運行時型別不安全現象。

一、 定義最簡單泛型類

package tigers;

class Generic1<T> { // 型別參數 T 為佔位符
    private T value;

    public void set(T value) { this.value = value; }
    public T get() { return value; }
}

二、 使用泛型類:具體化型別參數

public class GenericIdentify {
    public static void main(String[] args) {
        // 具體化為 String、Integer、Boolean
        Generic1<String> gStr = new Generic1<>();
        gStr.set("aaaaaaaaaaaaaaaaa");

        Generic1<Integer> gInt = new Generic1<>();
        gInt.set(1321423); // 自動裝箱 int → Integer

        Generic1<Boolean> gBool = new Generic1<>();
        gBool.set(true);   // 自動裝箱 boolean → Boolean

        System.out.println(gStr.get() + "\n" + gInt.get() + "\n" + gBool.get());

        // 型別擦除示範:透過原始類型繞過編譯期檢查
        ((Generic1) gInt).set("bbbbbbbbbbbbb"); // 未受檢轉型警告
        System.out.println(gInt.get()); // 運行時無誤,但破壞型別安全
    }
}

三、 編譯與執行

C:\tiger> javac -d c:\tiger\cls\ c:\tiger\src\*.java
Note: c:\tiger\src\GenericIdentify.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.

C:\tiger> java -classpath c:\tiger\cls tigers.GenericIdentify

四、 輸出結果

aaaaaaaaaaaaaaaaa
1321423
true
bbbbbbbbbbbbb

五、 核心概念深度解析

1. 型別參數 <T>

  • 慣例單一大寫字母:T (Type)、E (Element)、K/V (Key/Value)、N (Number)。
  • 可限定邊界:<T extends Comparable<T>>。
  • 不能為基本型別:Generic1<int> 編譯錯誤,必須用包裝類 Integer。

2. 型別擦除

  • 泛型資訊**僅存在編譯期**,編譯後 .class 檔中泛型類變為原始類型。
  • Generic1<String> 和 Generic1<Integer> 編譯後**同一個 Class 物件**。
  • 編譯器在呼叫端插入隱式強制轉型,保證編譯期型別安全。

3. 原始類型繞過檢查

((Generic1) gInt).set("string"); // 原始類型 Generic1,set 參數為 Object

編譯器發出 unchecked 警告,但允許通過。運行時因型別擦除,set(Object) 正常執行,導致 Generic1<Integer> 實例持有 String 物件。後續 get() 返回 String,若呼叫端當 Integer 用會拋 ClassCastException。

4. 自動裝箱/拆箱配合

gInt.set(1321423); // int → Integer 自動裝箱
int val = gInt.get(); // Integer → int 自動拆箱

簡化基本型別與包裝類互轉,但需注意 null 拆箱拋 NPE、自動裝箱產生物件影響效能。

六、 最佳實踐建議

  1. 消除 unchecked 警告:勿使用原始類型,善用 @SuppressWarnings("unchecked") 只在確定安全處局部抑制。
  2. 啟用 -Xlint:unchecked:建構腳本加入此參數,CI 流程視警告為錯誤。
  3. 避免泛型陣列:new T[10] 編譯錯誤,new Generic1[10] 原始類型陣列不安全,改用 List<T>。
  4. PECS 原則:extends (Producer) 用於讀取,super (Consumer) 用於寫入。

七、 總結

泛型以編譯期型別參數化換取型別安全與程式碼復用,但受限於型別擦除,運行時型別資訊丟失。理解擦除機制、原始類型風險與自動裝箱互動,是駕馭 Java 泛型的關鍵。

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