理解 Java 泛型擦除(Type Erasure),可以从「是什么、为什么、怎么表现、有什么影响」四个层面来看。
泛型擦除是指:
Java 在编译期会进行泛型类型检查,但在编译完成后(字节码中),泛型类型信息会被“擦掉”,统一替换为它们的上界或
Object。
简单说:
List<String> list = new ArrayList<>();
在 运行时,JVM 并不知道这是 List<String>,只知道是 List。
这是 历史兼容性 决定的。
List、Map 代码所以 Java 采用 编译期泛型 + 运行时擦除 的方案,实现:
✅ 这是一种“妥协式设计”
class Box<T> {
T value;
}
擦除后:
class Box {
Object value;
}
class Box<T extends Number> {
T value;
}
擦除后:
class Box {
Number value;
}
void print(List<String> list)
编译后等价于:
void print(List list)
new T()T obj = new T(); // 编译错误
原因:运行时不知道 T 是什么
T[] arr = new T[10]; // 错误
但允许:
List<String>[] arr = new List[10]; // 警告,但不安全
instanceofif (obj instanceof List<String>) // 错误
只能:
if (obj instanceof List)
void test(List<String> list) {}
void test(List<Integer> list) {}
❌ 编译错误(签名擦除后相同)
不是 完全没。
在以下地方仍保留泛型信息(通过 反射 + 元数据):
例如:
class MyList extends ArrayList<String> {}
可以通过:
MyList.class.getGenericSuperclass()
拿到 ArrayList<String>
⚠️ 但 对象实例本身不保存泛型
Java 泛型是“编译期的语法糖”,运行时不存在泛型。
✅ 编译期:帮你检查类型
❌ 运行期:擦成 Object / 上界
如果你愿意,我也可以:
你是更偏「面试理解」还是「源码级理解」?
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。