如何理解Java泛型擦除对反射运行时检查的潜在风险?
- 内容介绍
- 文章标签
- 相关推荐
本文共计659个文字,预计阅读时间需要3分钟。
它返回的是编译期保留的泛型签名数据,而不是运行时真实类型。例如:
为什么匿名子类能“泄露”具体类型参数
因为子类在定义时固定了泛型实参,该信息会写入子类的 Signature 属性并保留在字节码中。反射通过 getClass().getGenericSuperclass() 读取这个签名,才能拿到 String 这样的实际类型。
- 必须是**直接继承或匿名实现**,如
new ArrayList<string>() {}</string>;普通ArrayList<string> list = new ArrayList()</string>不行 - 只对**父类/接口声明的泛型字段或方法**有效,对局部变量、方法参数无效
- 如果父类用了通配符(如
List extends Number>),getActualTypeArguments()返回的是WildcardType,不能直接转成Class
instanceof 和 getClass() 为什么对泛型无效
这两者都依赖运行时类型信息,而泛型擦除后,List<string></string> 和 List<integer></integer> 的 getClass() 结果完全一样——都是 ArrayList.class。
本文共计659个文字,预计阅读时间需要3分钟。
它返回的是编译期保留的泛型签名数据,而不是运行时真实类型。例如:
为什么匿名子类能“泄露”具体类型参数
因为子类在定义时固定了泛型实参,该信息会写入子类的 Signature 属性并保留在字节码中。反射通过 getClass().getGenericSuperclass() 读取这个签名,才能拿到 String 这样的实际类型。
- 必须是**直接继承或匿名实现**,如
new ArrayList<string>() {}</string>;普通ArrayList<string> list = new ArrayList()</string>不行 - 只对**父类/接口声明的泛型字段或方法**有效,对局部变量、方法参数无效
- 如果父类用了通配符(如
List extends Number>),getActualTypeArguments()返回的是WildcardType,不能直接转成Class
instanceof 和 getClass() 为什么对泛型无效
这两者都依赖运行时类型信息,而泛型擦除后,List<string></string> 和 List<integer></integer> 的 getClass() 结果完全一样——都是 ArrayList.class。

