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>>(){});