在java中获取构造函数中的泛型类型

时间:2012-12-27 11:12:38

标签: java generics reflection constructor generic-programming

有没有办法在构造函数中找到泛型类型?

 public class geneticarg {
    public static void main(String[] args) {
    a<String> a1 = new a<String>("a");
    a<String> a2 = new a<String>(null); // gives NPE
    System.out.println(a1.getClazz());
    }
}

class a<T> {

private Class<T> clazz;
private T element;

public a(T clazz) {
this.clazz = (Class<T>) clazz.getClass();
this.element = clazz;
// what if clazz is null ?

}
//getter and setter
}

编辑:没有必要始终使用String。

3 个答案:

答案 0 :(得分:3)

您必须在构造函数中传递类型。您可以使用静态因子来避免必须设置两次。

A<String> a1 = A.wrap("a");
A<String> a2 = A.forClass(String.class);

class A<T> {
    private final Class<T> clazz;
    private final T element;

    private A(T t, Class<T> clazz) {
        this.clazz = clazz;
        this.element = t;
    }

    public static <T> A<T> wrap(T t) {
        return new A<T>(t, (Class) t.getClass());
    }

    public static <T> A<T> forClass(Class<T> clazz) {
        return new A<T>(null, clazz);
    }

    //getter and setter
}

答案 1 :(得分:3)

在您的情况下避免类型擦除的唯一方法是使用通用超类。您需要子类化您的泛型类型,然后您可以访问参数化类型,它可以通过反射API:

public abstract class a<T> {

    private Class<T> clazz;
    private T element;

    public a(T obj) {
        ParameterizedType type = (ParameterizedType) this.getClass().getGenericSuperclass();
        this.clazz = (Class<T>) type.getActualTypeArguments()[0];
        this.element = obj;
    }
}

class StringA extends a<String> {
    public StringA(String obj) {
        super(obj);
    }
}

答案 2 :(得分:0)

彼得非常正确。我想补充一些信息:

传递给构造函数的Class<T>实例称为类型标记