如何使用反射来构建通用子类型?

时间:2011-04-01 14:51:12

标签: java generics reflection factory-pattern

我正在使用Factory模式隐藏一些实例创建复杂性。 我有这个:

class FooInt extends Foo<int>;

我想这样做:

class<Foo<?>> fooType = FooInt.class;

所有派生类型的Foo都有一个带有2个参数的构造函数。所以我需要使用反射来创建子类型的实例:

Constructor<Foo<?>> ctor = fooType.getContructor(Blah.class, Blahblah.class);
return ctor.newInstance(blah, blahblah);

但是javac说:

"Type mismatch: cannot convert from Class<FooInt> to Class<Foo<?>>"

我做错了什么?是否有可能以这种方式使用反射?

3 个答案:

答案 0 :(得分:2)

尝试:Class<? extends Foo<?>> fooType = FooInt.class;

另一点是:

  • 班级类型为Class而非class(大写C);
  • 你不能在泛型中使用原始数据(使用Integer而不是int)

补充:这就是它的工作原理:

public class Foo<T> {

    private T value;

    public Foo(T value) {    
        this.value = value;
    }      
}

public class FooInt extends Foo<Integer>{
    public FooInt(Integer value) {
        super(value);
    }
}

public class FooDouble extends Foo<Double>{
    public FooDouble(Double value) {
        super(value);
    }
}

工厂(至少只有一行,但很多例外;-)):

import java.lang.reflect.InvocationTargetException;

public class Factory {

    <P, T extends Foo<P>> T build(Class<T> clazz, P param)
            throws IllegalArgumentException, SecurityException,
               InstantiationException, IllegalAccessException,
               InvocationTargetException, NoSuchMethodException {
        return clazz.getConstructor(param.getClass()).newInstance(param);
    }

    public static void main(String[] args)
            throws IllegalArgumentException, SecurityException,
                InstantiationException, IllegalAccessException,
                InvocationTargetException, NoSuchMethodException {

        Factory f = new Factory();

        System.out.println(f.build(FooInt.class, Integer.valueOf(1)));
        System.out.println(f.build(FooDouble.class, Double.valueOf(1.1)));
    }
}

答案 1 :(得分:1)

我认为拉尔夫就是这个意思。我个人觉得你不应该施展

 Class<? extends Foo> fooType = FooInt.class;

答案 2 :(得分:0)

java泛型中的

只是在编译时,在运行时不保存泛型类型的信息。所以没有办法使用反射来处理java中的泛型。