首页
学习
活动
专区
圈层
工具
发布
社区首页 >专栏 >为何说 Java 泛型是伪泛型?

为何说 Java 泛型是伪泛型?

原创
作者头像
程序员小假
发布2025-10-10 19:08:25
发布2025-10-10 19:08:25
1930
举报

前言

"Java 的泛型是伪泛型"这句话,其实是指 Java 的泛型实现方式“真正的泛型”(如 C++ 模板、C# 的泛型)相比,并不是在运行时保留类型信息,而是通过类型擦除(Type Erasure)来实现的。这就导致了一些限制和“看起来不像泛型”的行为。

一句话总结

Java 的泛型只在编译期有效,运行期被“擦除”成 Object 或边界类型,因此称为“伪泛型”。

🔍 什么是“类型擦除”?

Java 的泛型在编译后会被“擦除”,替换为它们的上界(通常是 Object),并插入强制类型转换代码。

举个例子:

代码语言:javascript
复制
List<String> list = new ArrayList<>();
list.add("hello");
String s = list.get(0);

编译后变成(近似):

代码语言:javascript
复制
List list = new ArrayList();
list.add("hello");
String s = (String) list.get(0);  // 强制类型转换

你会发现:运行时没有 List<String> 这个类型,只有 List


❗ 为什么说它是“伪泛型”?

特征

Java 泛型

真正的泛型(如 C#)

运行时保留类型信息

❌ 被擦除

✅ 保留

可以创建泛型数组

❌ 不允许

✅ 允许

可以用 T 创建对象

❌ 不行(擦除成 Object)

✅ 可以

可以用 T 做 instanceof

❌ 不行

✅ 可以

泛型类在运行时区分类型

❌ 不区分

✅ 区分


🧪 举个例子:运行时不区分类型

代码语言:javascript
复制
List<String> a = new ArrayList<>();
List<Integer> b = new ArrayList<>();

System.out.println(a.getClass() == b.getClass());  // true

输出是 true,说明 运行时 List<String>List<Integer> 是同一个类型


🧨 泛型擦除带来的限制

1. 不能创建泛型数组

代码语言:javascript
复制
T[] arr = new T[10];  // ❌ 编译错误

2. 不能用 Tinstanceof

代码语言:javascript
复制
if (obj instanceof T) { ... }  // ❌ 编译错误

3. 不能创建 T 的实例

代码语言:javascript
复制
T obj = new T();  // ❌ 编译错误

✅ 为什么 Java 不实现“真泛型”?

  1. 向后兼容:Java 1.5 引入泛型时,必须兼容旧版本字节码和类库。
  2. JVM 不需要改动:类型擦除避免了修改 JVM,降低了实现复杂度。
  3. 历史包袱:Java 最初设计时没有泛型,后来“打补丁”式加入。

✅ 总结

Java 的泛型是“编译期的语法糖”,运行时没有类型信息,因此被称为“伪泛型”。

如果小假的内容对你有帮助,请点赞评论收藏。创作不易,大家的支持就是我坚持下去的动力!

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。

如有侵权,请联系 cloudcommunity@tencent.com 删除。

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 前言
  • 一句话总结
  • 🔍 什么是“类型擦除”?
    • 举个例子:
    • 编译后变成(近似):
  • ❗ 为什么说它是“伪泛型”?
  • 🧪 举个例子:运行时不区分类型
  • 🧨 泛型擦除带来的限制
    • 1. 不能创建泛型数组
    • 2. 不能用 T 做 instanceof
    • 3. 不能创建 T 的实例
  • ✅ 为什么 Java 不实现“真泛型”?
  • ✅ 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档