AI协同学习:Java泛型 1. 泛型擦除后如何通过反射获取泛型信息? Java泛型擦除后,泛型类型信息会被擦除为它们的边界或Object。但在某些情况下(如继承泛型类或实现泛型接口),可以通过反射获取泛型信息的Type。 关键API: - Class.getGenericSuperclass() - 获取带泛型的父类 - Method.getGenericReturnType() - 获取方法返回值的泛型类型 - ParameterizedType.getActualTypeArguments() - 获取泛型参数的实际类型 示例代码: ```java import java.lang.reflect.*; import java.util.*; // 方法1:通过子类获取泛型父类的Type class StringList extends ArrayList {} Type parentType = StringList.class.getGenericSuperclass(); // parentType = java.util.ArrayList if (parentType instanceof ParameterizedType) { ParameterizedType pt = (ParameterizedType) parentType; Type[] typeArgs = pt.getActualTypeArguments(); for (Type typeArg : typeArgs) { System.out.println("Type arg: " + typeArg); // java.lang.String } } // 方法2:通过方法返回值获取泛型信息 Method method = GenericReflection.class.getMethod("getCache"); Type returnType = method.getGenericReturnType(); if (returnType instanceof ParameterizedType) { ParameterizedType pt = (ParameterizedType) returnType; System.out.println("Return type args: " + Arrays.toString(pt.getActualTypeArguments())); } ``` 2. Cache 代码审查 Cache 实现分析: 优点: - 使用了合理的缓存数据结构 - 实现了过期机制 - 包含 containsKey、remove、clear 等完整API - 内部类 CacheEntry 封装良好 问题和建议: 1. 线程不安全 - 如果多线程并发访问会有问题,建议添加同步或使用 ConcurrentHashMap 2. 泛型信息丢失 - CacheEntry 中保存了 V value,但由于类型擦除,无法在运行时获取 V 的具体类型 3. remove 方法在并发场景下可能有空指针问题 思考题:为什么Java泛型不支持基本类型? 核心原因:历史兼容性和类型系统设计 1. 类型擦除机制 - Java泛型在运行时会被擦除为 Object。基本类型(如 int、long)不是对象,不能赋值给 Object,所以无法进行类型擦除。 编译后变成: ArrayList → ArrayList // int不是Object ArrayList → ArrayList // Integer是Object 2. 自动装箱的性能开销 - 虽然有 int ↔ Integer 自动装箱,但这会带来额外的性能开销。Java设计者选择不让泛型支持基本类型,以保持性能。 3. 向后兼容性 - Java 1.5 才引入泛型,为了兼容旧代码(没有泛型时 ArrayList 可以存任何对象),选择用类型擦除实现。 简单记忆:Java泛型本质是"伪泛型",它只在编译期提供类型检查,运行时没有泛型信息。基本类型不是对象,无法参与类型擦除。