我有这段代码:
public class JsonFileHandler<T> {
public T getContent(File file) {
T t = null;
ObjectMapper mapper = new ObjectMapper();
if (!file.exists()) {
return null;
} else try {
t = mapper.readValue(file, T.class);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
return t;
}
}
但是我在这一行得到了编译错误:
t = mapper.readValue(file, T.class);
有这个签名:
public <T> T readValue(File src, Class<T> valueType)
我该如何解决这个问题?
答案 0 :(得分:2)
我认为您唯一的选择是匹配readValue
的签名:
public T getContent(File file, Class<T> clazz) {
//
t = mapper.readValue(file, clazz);
//
}
或者,您可以在类构造函数级别执行此操作:
public JsonFileHandler(Class<T> clazz) { this.clazz = clazz; }
答案 1 :(得分:0)
你不能,编译掉类型参数。它被称为类型擦除。
答案 2 :(得分:0)
由于运行时擦除,T
在运行时未知。最简单的解决方案是将类型标记传递给构造函数:
public class JsonFileHandler<T> {
private final Class<T> cls;
public JsonFileHandler(Class<T> cls) {
this.cls = cls;
}
public T getContent(File file) {
T t = null;
ObjectMapper mapper = new ObjectMapper();
if (!file.exists()) {
return null;
} else try {
t = mapper.readValue(file, cls);
} catch (IOException e) {
e.printStackTrace();
throw new RuntimeException(e);
}
return t;
}
}
答案 3 :(得分:0)
Java的有限泛型系统不允许您使用'T.class'。 (Scala在这方面更强大)
要解决此问题,您必须将Class实例传递给getContent方法。
public T getContent(File file, tpe: Class<T>) { ... }
如果你正在使用Java 8(如果没有,为什么不呢?),那么考虑返回一个Optional来取消null和NPE。 更好的方法是返回表示成功或失败的内容(如Scala的Try),这样您就不必使用null或抛出异常并在正确的位置正确处理错误。
答案 4 :(得分:0)
你可以做的就是去上课:
t = (T) mapper.readValue(file, Object.class);
这与您想要的语义相同!