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

Java 泛型通配符與 C# 泛型約束深度對比

     編輯:Java 相關知識

核心差異:類型系統層面的擦除 vs 具體化

Java 泛型採用類型擦除,編譯期僅作語法檢查,運行期全部擦除為 Object;C# 泛型由 CLR 直接支持,運行期保留具體類型資訊(具體化)。這一根本差異導致 Java 需要通配符(?)來表達「未知類型的父子關係」,而 C# 則通過 where 子句在聲明處約束類型參數。

Java 通配符三大模式

語法含義典型場景
List<?>無界通配符,等價於 List<? extends Object>僅讀取元素、不關心具體類型的容器操作
List<? extends Number>上界通配符:只能是 Number 或其子類讀取數值類型集合(如求和、最大值),不可寫入
List<? super Integer>下界通配符:只能是 Integer 或其父類寫入 Integer 及其子類對象,讀取只能作為 Object
// 無界通配符示例:打印任意 List 內容
public void printAll(List<?> list) {
    for (Object o : list) System.out.println(o);
}

// 上界通配符:計算 Number 子類列表的雙精度和
public double sum(List<? extends Number> nums) {
    double s = 0;
    for (Number n : nums) s += n.doubleValue(); // 只能讀取
    return s;
}

// 下界通配符:向列表添加 Integer
public void addIntegers(List<? super Integer> list) {
    list.add(10);      // OK
    list.add(new Integer(20)); // OK
    // list.add(new Object()); // 編譯錯誤
}

C# 泛型約束語法


// 類約束:T 必須是引用類型,U 必須是值類型
class MyClass<T, U> where T : class where U : struct { }

// 介面約束:TKey 必須實現 IComparable、IEnumerable;TVal 必須實現 IMyInterface
interface IMyInterface { }
class Dictionary<TKey, TVal> 
    where TKey : IComparable, IEnumerable
    where TVal : IMyInterface
{
    public void Add(TKey key, TVal val) { }
}

// 建構函數約束:T 必須有無參建構函數
class Factory<T> where T : new() {
    public T Create() => new T();
}

C# 約束在聲明處綁定,編譯器可生成專用 IL 代碼,運行期無裝箱/拆箱開銷,性能優於 Java 擦除模式。

Java 多重界限寫法

<T extends Number & Serializable>  // 注意用 & 而非逗號
class Apple<T> { }

總結對比

維度JavaC#
運行期類型擦除為 Object/界限類型保留具體類型(具體化)
多態表達使用通配符 ? extends/super聲明處約束 where T : ...
基本類型支持不支持(需裝箱)原生支持 int、double 等
性能裝箱/拆箱、類型轉換開銷零開銷,專用代碼路徑

理解兩者設計哲學差異,有助於在跨語言架構設計中做出更合適的泛型建模決策。

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