如何将泛型转换为Class <t>?

时间:2015-07-07 08:01:24

标签: java generics

我有这段代码:

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)

我该如何解决这个问题?

5 个答案:

答案 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);

这与您想要的语义相同!