如何在编译时指定泛型类信息?

时间:2014-06-26 14:58:25

标签: java generics

我有一个如下定义的类:

public class GenericClass<T> {

 private final Class<T> type;

 public GenericClass(Class<T> type) {
      this.type = type;
 }

 public Class<T> getMyType() {
     return this.type;
 }
}

使用该类代码很容易使用非泛型类型实例化该类的新实例。例如:

GenericClass<String> c = new GenericClass<String>(String.class)

我的问题如下。如何使用泛型类型创建类的新实例?例如:

GenericClass<List<String>> c = new GenericClass<List<String>>(...)

如果我放List<String>.class编译器给我一个错误。在编译时,我应该使用哪种语法向构造函数指定泛型类型的正确类?

4 个答案:

答案 0 :(得分:1)

通用不知道也不关心指定的通用类,因此,没有List<String>.class,只有List.class。你有没有考虑过通配符? List<?>.class应该返回什么? List<? extends AnotherClass>.class?所以不,你不能知道泛型在编译时持有什么特定的类,主要是因为它可以包含仅在运行时完全指定的不同类。

答案 1 :(得分:0)

将泛型写入类类型(因此在运行时使用反射使它们可用)的唯一方法是创建GenericClass的子类。即使是匿名的内部阶级也能完成这项工作:

GenericClass<List<String>> c = new GenericClass<List<String>>(...){};

(注意尾随{})。

答案 2 :(得分:0)

怎么样:

public class GenericClass<T> {
    Class<T> type;

    @SuppressWarnings("unchecked")
    public GenericClass() {
        Type type = ((ParameterizedType) getClass()
                .getGenericSuperclass()).getActualTypeArguments()[0];
        if (type instanceof Class<?>)
            this.type = (Class<T>)type;
        else if (type instanceof ParameterizedType)
            this.type = (Class<T>) ((ParameterizedType)type).getRawType();
        else
            this.type = null;
    }

    public Class<T> getType() {
        return type;
    }
}

用法:

public static void main(String[] args) {
    GenericClass<Integer> g = new GenericClass<Integer>() {};
    System.out.println(g.getType());

    GenericClass<List<String>> g2 = new GenericClass<List<String>>() {};
    System.out.println(g2.getType());
}

答案 3 :(得分:0)

您的问题是只有一个List类对象,您可以从List.class获取该对象。但它是Class<List>Class<List<Object>>Class<List<String>>还是Class<List<?>>等?它只能有一种类型,Java设计者选择Class<List>(它是唯一安全的选择)。如果你真的想要Class<List<String>>,那么你必须做一些未选中的演员表:

GenericClass<List<String>> c =
    new GenericClass<List<String>>((Class<List<String>>)(Class<?>)List.class);