在<T>java中,Generic T,Class,JavaType,TypeReference和SolveType之间有什么区别?



我尝试编写一个通用的数据加载器。下面是加载器逻辑(代码片段1 (CS1)):

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

这里是我使用加载器的代码剪切器(代码片段2 (CS2)):

String[] stringArray;
//Todo something

stringArray = new Loader<String[]>().getData("<path>", String[].class);

我的第一个问题是:如果我在CS2中传递类型信息:new Loader<String[]>(),为什么我不能在这里使用这个泛型信息:return objectMapper.readValue(new File(testDataPath), new T().getClass());?

在这一点上,我混淆了项T, Class<>和其他类型相关的类,允许在objectMapper的readValue函数中作为第二个参数传递(Class<>, JavaType, typerefence, ResolvedType)。

所以有人能解释我为什么我不能使用T,因为我尝试和Class<>, JavaType, typerefence, ResolvedType之间的区别是什么?

谢谢!

T只是实际类型的占位符,它将在运行时提供。因此,编译器不知道T是什么,因此不允许您执行T.classnew T()之类的操作。但是编译器可以帮助你确保你期望用T类型操作的地方,你会得到真正的T,也就是说你的代码类型安全。

关于Jackson的TypeReference,它对集合和参数化类很有用,例如:

new TypeReference<List<String>() {}
new TypeReference<Foo<Bar>() {}

如果您使用的是Class<T>,您将无法提供有关类型为:Class<List.class>,Class<Foo.class>的参数的信息。

因此,只有在解析T类型的非泛型对象时,Class<T>才很方便。

有关泛型的更多信息,请参阅Java语言规范:

  • §4.5。参数化的类型。

  • §4.6。类型擦除。

最新更新