从该methods参数的属性获取方法返回类型

时间:2015-05-19 14:11:47

标签: java generics

我有一个具有内部Class属性的C类:

public class C{
   private Class<?> clazz;

   public void setClazz(Class<?> c){
      this.clazz = c;
   }

   public Class<?> getClazz(){
      return clazz;
   }
}

我希望在另一个类中声明一个方法,所以它的返回类型是C.clazz的类型:

public class D{
    public <T> T getInstance(C c){
       //doesn't compile
       //some reflective code to set T to c.getClazz?
       return (c.getClazz.newInstance());
    }
}  

所以,例如,getInstance(c),其中c将clazz设置为Class<B>,会返回一个B的新实例。有没有办法用反射做到这一点?

3 个答案:

答案 0 :(得分:5)

class C<T>{
    private final Class<T> clazz;

    C(Class<T> clazz) {
        this.clazz = clazz;
    }

    public Class<T> getClazz(){
        return clazz;
    }
}

class D{
    public <T> T getInstance(C<T> t) throws IllegalAccessException, InstantiationException {
        return t.getClazz().newInstance();
    }
}


public static void main() throws Exception {
    C<String> c = new C<>(String.class);
    D d = new D();
    String s = d.getInstance(c);
    System.out.println("String = " + s);
}

这也是存储泛型类型信息的经典方法。但是我不明白你为什么要在getInstace内使用D方法。我宁愿把它变成C里面的静态方法。

你可以调整类似的策略,即使它是一个包含java.lang.reflect.Array.newInstance(t.getClazz(),10);的数组,而不仅仅是t.getClazz().newInstance()

甚至还有其他方法可以捕获泛型类型信息。 Read这对于更复杂的事情。

答案 1 :(得分:0)

您需要getClazz()并转换为T

public class D {
    public <T> T getInstance(C c) throws InstantiationException, IllegalAccessException {
        return (T)(c.getClazz().newInstance());
    }
}

答案 2 :(得分:0)

public class C<T> {
    private Class<T> clazz;

    public void setClazz(Class<T> c){
        this.clazz = c;
    }

    public Class<T> getClazz(){
        return clazz;
    }
}

public class D {
    public <T> T getInstance(C<T> c){
       //doesn't compile
       //some reflective code to set T to c.getClazz?
       return c.getClazz().newInstance();
    }
    public <T> T getInstance2(C c, Class<T> clazz){
       //doesn't compile
       //some reflective code to set T to c.getClazz?
       return clazz.cast(c.getClazz().newInstance());
    }
}

getInstance需要带有T param的C,否则getInstance2需要一个Class作为参数,并进行不安全的转换(您可以添加一个检查)。