我尝试编写一个通用的数据加载器。下面是加载器逻辑(代码片段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.class
或new 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。类型擦除。