副标题 / 摘要

Java 泛型在运行时会被擦除,导致不同类型参数的 List 拥有相同 Class。本文解释原因与影响。

目标读者

  • 使用 Java 泛型的开发者
  • 想理解类型系统限制的人
  • 进行 API 设计的工程师

背景 / 动机

Java 泛型是编译期特性。
在运行时,类型参数会被擦除,这会影响反射与类型判断。

核心概念

  • 类型擦除:泛型信息在运行时消失
  • 编译期检查:类型安全主要在编译期保证
  • 运行时类型:只剩原始类型

实践指南 / 步骤

  1. 理解泛型只在编译期起作用
  2. 避免依赖运行时泛型信息
  3. 用显式 Class 参数传递类型
  4. 在反射场景保持谨慎

可运行示例

import java.util.ArrayList;

public class ErasureDemo {
    public static void main(String[] args) {
        ArrayList<Integer> li = new ArrayList<>();
        ArrayList<Float> lf = new ArrayList<>();
        System.out.println(li.getClass() == lf.getClass()); // true
    }
}

解释与原理

泛型类型参数在编译后被擦除为原始类型(如 ArrayList)。
因此运行时类对象相同。

常见问题与注意事项

  1. 这会影响类型安全吗?
    编译期仍保证类型安全,但运行时反射可能不安全。

  2. 为什么 Java 设计成这样?
    为了兼容旧版本与字节码格式。

  3. 如何避免问题?
    通过类型标记或显式传入 Class。

最佳实践与建议

  • 不要依赖运行时泛型判断
  • 在反射场景显式传递类型
  • 理解擦除限制设计更稳健的 API

小结 / 结论

类型擦除是 Java 泛型的根本限制。
理解这一点可以避免许多运行时误解。

参考与延伸阅读

  • Java Generics Type Erasure
  • Effective Java 泛型章节

元信息

  • 阅读时长:5~7 分钟
  • 标签:Java、泛型
  • SEO 关键词:类型擦除, Java 泛型
  • 元描述:解释 Java 类型擦除的机制与影响。

行动号召(CTA)

检查你的反射代码,确认是否依赖运行时泛型信息。