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

J2SE 5.0 泛型集合開發指南:從泛型類設計到自定義 Queue 實現

     編輯:Java 程式設計入門

前言:泛型為集合框架注入類型安全

J2SE 5.0 引入泛型,徹底改變集合 API 設計方式。本文將演示如何創建支持泛型的自定義類,並以 Queue<E> 為例,構建與 for-each 循環無縫協作的類型安全集合。

一、創建支持泛型的類:類型參數聲明與使用

1. 多類型參數聲明

public class Example<ONE, TWO, THREE> {
    private ONE one;
    private TWO two;
    private THREE three;

    public ONE getOne() { return one; }
    public void setOne(ONE one) { this.one = one; }
    // ... 其餘 getter/setter 省略

    public static void main(String[] args) {
        // 實例化時指定具體類型
        Example<Double, Integer, String> ex = new Example<Double, Integer, String>();
        ex.setOne(1.5);
        ex.setTwo(2);
        ex.setThree("Three");
    }
}
  • <ONE, TWO, THREE> 為類型參數(佔位符)
  • 實例化時用實際類型替換,編譯器將進行類型檢查
  • 若不指定(原始類型),默認擦除為 Object,失去類型安全

2. 泛型方法與類型推斷

public <T> void print(T obj) {
    System.out.println(obj);
}
// 調用時編譯器自動推斷 T 類型
print("Hello"); // T 推斷為 String
print(123);     // T 推斷為 Integer

二、自定義泛型 Queue 實戰

1. 設計目標

  • 先進先出 (FIFO) 語義
  • 支持 push(E)、pop()、size()、isEmpty()、clear()
  • 內部委託 ArrayList<E> 存儲
  • 拋出自定義 QueueException 而非返回 null

2. 完整代碼

package com.heatonresearch.examples.collections;

import java.util.*;

public class Queue<E> {
    private final ArrayList<E> list = new ArrayList<E>();

    public void push(E obj) {
        list.add(obj);
    }

    public E pop() throws QueueException {
        if (size() == 0) {
            throw new QueueException("Queue is empty");
        }
        E result = list.get(0);
        list.remove(0);
        return result;
    }

    public boolean isEmpty() {
        return list.isEmpty();
    }

    public int size() {
        return list.size();
    }

    public void clear() {
        list.clear();
    }
}

// 自定義異常
class QueueException extends Exception {
    public QueueException(String msg) { super(msg); }
}

3. 使用示例

Queue<String> q = new Queue<String>();
q.push("A");
q.push("B");
q.push("C");

while (!q.isEmpty()) {
    System.out.println(q.pop()); // 輸出 A, B, C
}

// 配合 for-each 循環(需實現 Iterable<E>)
// 此處為演示,Queue 未實現 Iterable,若實現則可:
// for (String s : q) { ... }

三、泛型集合與 for-each 循環的協作原理

1. 編譯器語法糖轉換

// 源碼
for (String s : list) { ... }

// 編譯器生成等價字節碼
for (Iterator<String> it = list.iterator(); it.hasNext(); ) {
    String s = it.next();
    ...
}
  • 數組:轉為索引遍歷 for (int i=0; i<arr.length; i++)
  • Collection:轉為 Iterator 遍歷
  • 性能無損耗,純編譯期轉換

2. 為何不用 foreach/in 關鍵字

  • for 復用現有關鍵字,避免破壞現有代碼中變量名 foreach/in
  • in 常用作 System.in 等標識符,引入關鍵字衝突風險極大
  • 冒號 : 在語法上無歧義,且類似數學「屬於」符號

四、進階話題:類型擦除與橋接方法

  • 運行時泛型信息被擦除,Queue<String> 與 Queue<Integer> 共用同一 Class 對象
  • 編譯器自動生成橋接方法保證多態性
  • 禁忌:不可創建泛型數組 new E[10]、不可 instanceof 具體泛型類型

五、最佳實踐清單

  1. 所有集合字段、方法參數、返回值**強制聲明泛型類型**
  2. 優先使用 List<E>、Set<E>、Map<K,V> 接口而非實現類
  3. 自定義集合實現 Iterable<E> 以支持 for-each
  4. 通配符 <? extends T>/<? super T> 靈活處理協變/逆變場景
  5. 避免原始類型與泛型混用,啟用編譯器 -Xlint:unchecked 檢查

六、結語

泛型將類型安全從運行時前移至編譯期,自定義泛型集合僅需在類聲明添加 <E>、內部集合泛化、方法簽名參數化。結合 for-each、Iterable、通配符等特性,即可構建出與 JDK 集合框架無縫融合的高質量組件。建議在項目中全面推行泛型化重構,消除 ClassCastException 隱患,提升代碼可讀性與重構安全性。

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