每个 Java 程序员都应该知道,Java中的泛型是”伪泛型“,是为了兼容 JDK1.5 之前的代码而采用”类型擦除“这种方式实现的”伪泛型“,关于 Java 为什么要采用类型擦除而不是实现真正的泛型,我有时间再写文章说明,因为现在已经 2025年3月4日 00:15:03 了,赶紧写篇短的博客,然后睡觉了。
我们知道,在 Java 中你定义的泛型中的类型,在编译之后就不存在了。
那么 C# 中的泛型是怎样的呢?它们之间的区别是什么呢 ?它们之间主要的区别如下:
关键区别总结
- 类型擦除:
- Java 的泛型在编译时进行类型擦除,运行时无法获取泛型类型信息。
- C# 的泛型在运行时保留类型信息。
- 值类型支持:
- Java 的泛型不支持原始类型,必须使用包装类。
- C# 的泛型支持原始类型。
- 协变和逆变:
- Java 通过通配符实现有限的协变和逆变。
- C# 通过
out
和in
关键字实现更灵活的协变和逆变。
来直接看个例子,看一下 C# 中的真泛型:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
public class Test_Generic2 { public static void run() { // 创建一个泛型类的实例,类型参数为 int var intContainer = new Container<int>(42); intContainer.PrintType(); // 创建另一个泛型类的实例,类型参数为 string var stringContainer = new Container<string>("Hello, Generics!"); stringContainer.PrintType(); } } // 定义一个泛型类 class Container<T> { private T _value; public Container(T value) { _value = value; } // 打印泛型类型的信息 public void PrintType() { // 获取泛型类型 T 的类型信息 Type type = typeof(T); Debug.WriteLine($"Type of T: {type}"); Debug.WriteLine($"Value: {_value}"); } } |
而输出结果如下:

可以看到,在 C# 中你定义的泛型,在程序运行阶段是可以拿到元素真正的类型的!