Java泛型T、Class<T>等类型类差异及泛型信息无法使用问题
泛型数据加载器相关问题解答
代码片段
CS1:泛型Loader类
public class Loader<T> { private ObjectMapper objectMapper = new ObjectMapper(); public T getData(String testDataPath , Class<T> resultClassType) throws IOException { return objectMapper.readValue(new File(testDataPath), resultClassType); } }
CS2:Loader使用代码
String[] stringArray; //Todo something stringArray = new Loader<String[]>().getData("<path>", String[].class);
问题解答
1. 为什么无法通过new T().getClass()使用泛型信息?
这是Java泛型类型擦除导致的:
- Java泛型是编译期特性,编译完成后字节码里的泛型参数
T会被擦除成它的上界(未指定则为Object),运行时JVM完全不知道实例化Loader<String[]>时指定的具体类型。 - 另外
new T()本身不合法:编译器无法确定T是否有无参构造方法,运行时也找不到对应的类实例化,强行执行会抛出InstantiationException或类型转换异常。
2. 泛型T、Class<>及Jackson相关类型的差异
泛型T
只是编译期的类型占位符,仅用于编译时的类型安全检查,运行时会被完全擦除,无法获取任何真实的类型元数据。
Class<>
是JVM中表示类/接口的元数据对象,每个类在JVM中只有一个Class实例。它能表示具体的非泛型类(如String.class)、数组类(如String[].class),但无法区分带泛型参数的类型——比如List<String>和List<Integer>的Class都是List.class,无法识别泛型参数差异。
Jackson相关类型
Jackson为解决Java泛型擦除导致的类型信息丢失问题,提供了以下专用类型工具:
- JavaType:Jackson核心的类型表示,能完整保留泛型参数信息。比如要表示
List<String>,可通过objectMapper.getTypeFactory().constructParametricType(List.class, String.class)创建,Jackson依靠它正确反序列化泛型对象。 - TypeReference:通过匿名子类特性捕获泛型信息(子类的泛型参数不会被完全擦除)。比如
new TypeReference<List<String>>() {},Jackson能从这个匿名类的字节码中获取List<String>的完整类型,常用于泛型集合的反序列化。 - ResolvedType:是Jackson对
java.lang.reflect.Type的扩展,提供更强大的类型查询能力(如获取泛型参数、父类类型、判断是否为数组等),JavaType是它的实现类之一。
内容的提问来源于stack exchange,提问作者HowToTellAChild
相关产品推荐
相关产品推荐

