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

如何从泛型类型的抽象类调用方法(使用java反射),java,reflection,Java,Reflection,课程简化: public abstract class AbstractFieldGroupBind<T> { public Class<T> beanClass; public BeanFieldGroup<T> binder; public void initGroupBinder(Object vaadinComponent){ binder = new BeanFieldGroup<T>(bean

课程简化:

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);
    }

}
If将调用类,但不调用类型。它不会像这样工作

我还可以得到泛型超类,然后在extends中找到类型集。 但如何将其组合起来调用方法,如:

Method method = theFGBClass.getClass().getSuperclass().getDeclaredMethod("initGroupBinder", Object.class);
method.invoke(....)
public void initGroupBinder(Object vaadinComponent){
    binder = new BeanFieldGroup<Cinema>(Cinema.class);
    binder.bindMemberFields(vaadinComponent);
}
public void initGroupBinder(对象组件){
binder=新Beanfield组(Cinema.class);
binder.bindMemberFields(vaadinComponent);
}

添加:我通过Spring by context.getBean()在composer中获得类“StammdataEditFGB”。此构造在Spring上下文中运行。因此,使用Spring的ReflectionUtils的解决方案也是非常受欢迎的。

当您实例化类
StammdataEditFGB
的对象时,您已经将类型信息传递给了超类。因此,当您调用
OffGBClass.getClass().getSuperClass()
时,您将得到一个
AbstractFieldGroupBind
类,该类处理
Cinema
对象。

找到了解决方案!有两个问题

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();
        }
    }
}
解决这个问题后,下一个问题是泛型类型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;
    }
}
公共抽象类AbstractFieldGroupBind实现IFieldGroupBind{
保护豆地组粘合剂;
@凌驾
public void initGroupBinder(对象视图){
binder=新BeanFieldGroup(getClassForT());
binder.bindMemberFields(视图);
}
@凌驾
公共项目(T项目){
binder.setItemDataSource(项目);
}
@凌驾
公共T getItem(){
返回binder.getItemDataSource().getBean();
}
@抑制警告(“未选中”)
私有类getClassForT(){
键入superClazz=this.getClass().getGenericSuperclass();
类型tClazz=((ParameteredType)superClazz).getActualTypeArguments()[0];
返回(类)tClazz;
}
}

现在它工作了

查看
语句
表达式
对象。我也这么认为。但事实并非如此。绑定器是用类初始化的,而不是用Cinema初始化的。您必须记住,类型变量在运行时不存在。检查此链接。如果需要该类型的类,则必须从子类设置它。
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;
    }
}