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

Java 泛型通配符 `? super T` vs `? extends T`:PECS 原則圖解與實戰

     編輯:程式設計綜合問答

核心口訣:PECS (Producer Extends, Consumer Super)

  • **只讀取 (Producer)** → 用 `? extends T`
  • **只寫入 (Consumer)** → 用 `? super T`
  • **既讀又寫** → 不用通配符,用確切類型 `T`

你的代碼場景分析


Collection   // Consumer: 只能往裡放 Cat 或其子類 (安全)
Collection // Producer: 只能從裡取 Animal 或其父類 (安全)

詳細規則對比

通配符可讀取類型可寫入類型典型用例
`? extends Animal``Animal` (及父類 Object)**無** (編譯錯誤,除 null)遍歷、複製、流處理
`? super Cat``Object` (丟失具體類型)`Cat` 及其子類添加元素、比較器、回調
`?` (無界)`Object`**無**只關心 size/clear/isEmpty 等與類型無關操作

代碼驗證


List consumer = new ArrayList(); // Animal 是 Cat 父類,合法
consumer.add(new Cat());      // ✅ Cat 是 Cat
consumer.add(new Kitty());    // ✅ Kitty 是 Cat 子類
consumer.add(new Animal());   // ❌ Animal 不是 Cat 子類
Object o = consumer.get(0);   // 只能作為 Object 讀取

List producer = new ArrayList(); // Cat 是 Animal 子類,合法
Animal a = producer.get(0);   // ✅ 取出的是 Animal
producer.add(new Cat());      // ❌ 編譯錯誤:不能保證列表真實類型能裝 Cat
producer.add(new Animal());   // ❌ 同上

你的具體方法簽名建議


// printA: 只需讀取元素並打印 → Producer → extends
public static void printA(Collection c) {
    for (Animal a : c) System.out.println(a);
}

// printB: 若需往集合添加 Cat → Consumer → super
// 但打印通常不添加,故 extends 更合適
public static void printB(Collection c) { ... }

// 統一用 extends Animal 即可

記憶模型:類型擴散方向


         Animal
           ▲
           │ extends (向上擴散,讀取安全)
           ▼
         Cat
           ▲
           │ super (向下擴散,寫入安全)
           ▼
        Kitty
  • `extends` 向**上**看:能安全讀出父類型。
  • `super` 向**下**看:能安全寫入子類型。

原回答補充

原最佳回答僅貼鏈接。上文提供 PECS 原則、規則對比表、代碼驗證、記憶模型圖解,可直接指導實戰。

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