java 泛型真的会被擦除么

https://zhuanlan.zhihu.com/p/292983882

https://mp.weixin.qq.com/s/Yn9CIfgLozZNs_xfSo1ZmA

被擦除的泛型
泛型被擦除的一个典型例证,是可以使用反射技术向泛型集合添加非泛型允许类型元素。例如向 ArrayList<String> 中插入 Integer 变量。

被擦除到上边界的泛型
声明泛型的类在编译后被擦除到上边界,这也支撑了 extends 通配符预支公共方法。没有被 extends 通配符修饰的泛型被擦除到 Object。

未被擦除的泛型
父类泛型、成员变量、方法入参和返回值使用到的泛型信息都会保留,并能在运行阶段获取。

public class Clazz extends ArrayList<String> {
        public Map<String, Integer> field;

        public Set<String> function(List<Number> list) {
            return null;
        }
    }

public static void main(String[] args) throws Exception {
        // 获取父类泛型
        System.out.println("GenericSuperclass:" + ((ParameterizedType) (Clazz.class.getGenericSuperclass())).getActualTypeArguments()[0]);
        // 获取成员变量泛型
        Field field = Clazz.class.getDeclaredField("field");
        for (Type fieldType : ((ParameterizedType) (field.getGenericType())).getActualTypeArguments()) {
            System.out.println("field:" + fieldType.getTypeName());
        }
        // 获取方法入参和返回值泛型
        Method method = Clazz.class.getDeclaredMethod("function", List.class);
        for (Type type : method.getGenericParameterTypes()) {
            System.out.println("method param:" + ((ParameterizedType) type).getActualTypeArguments()[0]);
        }
        System.out.println("method return:" + ((ParameterizedType) method.getGenericReturnType()).getActualTypeArguments()[0]);
    }

 

由此可见,java 类定义中使用的泛型,都被做为类信息的一部分记录在类文件中,并提供反射方法在运行时获取。fastjson 反序列化借助了父类泛型:

List<String> list = JSON.parseObject(json, new TypeReference<List<String>>(){});
posted @ 2023-06-28 13:49  zbjice  阅读(62)  评论(0)    收藏  举报