如何从具有泛型类型的抽象类调用方法(使用java反射)

时间:2014-05-28 09:22:15

标签: java reflection

课程简化:

public abstract class AbstractFieldGroupBind<T> {

    public Class<T> beanClass;
    public BeanFieldGroup<T> binder;

    public void initGroupBinder(Object vaadinComponent){
        binder = new BeanFieldGroup<T>(beanClass);
        binder.bindMemberFields(vaadinComponent);
}


public class StammdataEditFGB extends AbstractFieldGroupBind<Cinema> {

    public void pushItem(Item item) {
        binder.setItemDataSource(item);
    }

}

现在我尝试通过编写器类调用方法“initGroupBinder”。 如果调用方法如:

Method method = theFGBClass.getClass().getSuperclass().getDeclaredMethod("initGroupBinder", Object.class);
method.invoke(....)

如果将调用该类但没有Type。它不会像这样工作。

我也可以获得泛型超类,并在那里找到扩展中的类型集。 但是如何将它组合起来调用方法如:

public void initGroupBinder(Object vaadinComponent){
    binder = new BeanFieldGroup<Cinema>(Cinema.class);
    binder.bindMemberFields(vaadinComponent);
}

ADD:我通过context.getBean()通过Spring获得作曲家中的“StammdataEditFGB”类。此构造在Spring上下文中运行。因此,Spring的ReflectionUtils的解决方案也非常受欢迎。

2 个答案:

答案 0 :(得分:1)

找到解决方案!有2个问题。

1。 getDeclaratedMedothod将找不到扩展类中的方法。通过使用getMethod,您将在抽象类中获得方法(方法必须是公共的) 这里有一个小例子来展示。

 public class Test {

    public abstract class AbstractPerson{
        public void callMe(){
            System.out.println("Method callMe() in AbstractPerson");
        }
    }

    public class Person extends AbstractPerson{}

    public static void main(String[] args) {

        Test test = new Test();
        Person person = test.new Person();

        try {
            Method method;
            System.out.println("### Use getMethod");
            method = person.getClass().getMethod("callMe", (Class<?>[]) null);
            method.invoke(person, null);
            System.out.println("### Use getDeclaredMethod");
            method = person.getClass().getDeclaredMethod("callMe", (Class<?>[]) null);
            method.invoke(person, null);
        } 
        catch (Exception e) {
            e.printStackTrace();
        }
    }
}

控制台:

### Use getMethod
Method callMe() in AbstractPerson
### Use getDeclaredMethod
java.lang.NoSuchMethodException: Test$Person.callMe()
    at java.lang.Class.getDeclaredMethod(Class.java:2004)
    at Test.main(Test.java:27)

解决了这个问题之后,下一个问题就出现了泛型类型T.

2。 BeanFieldGroup无法像我一样初始化。当然beanClass是空的。
这里是正确设置BeanFieldGroup beanClass的解决方案:

public abstract class AbstractFieldGroupBind<T> implements IFieldGroupBind<T>{

    protected BeanFieldGroup<T> binder;

    @Override
    public void initGroupBinder(Object view){
        binder = new BeanFieldGroup<T>(getClassForT());
        binder.bindMemberFields(view);
    }

    @Override
    public void pushItem(T item) {
        binder.setItemDataSource(item);
    }

    @Override
    public T getItem() {
        return binder.getItemDataSource().getBean();
    }

    @SuppressWarnings("unchecked")
    private Class<T> getClassForT(){
        Type superClazz = this.getClass().getGenericSuperclass();
        Type tClazz = ((ParameterizedType)superClazz).getActualTypeArguments()[0];
        return (Class<T>) tClazz;
    }
}

现在有效!

答案 1 :(得分:0)

当您实例化类StammdataEditFGB的对象时,您已经将类型信息传递给超类。因此,当您致电theFGBClass.getClass().getSuperClass()时,您将获得一个处理AbstractFieldGroupBind个对象的Cinema类。