derlinuxer
derlinuxer

Reputation: 574

How To invoke a Method (with java reflection) from abstract class with generic type

The Classes simplified:

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

}

Now I try to invoke the method "initGroupBinder" by a composer Class. If invoke the method like:

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

If will call the class but without the Type . It will not work like this.

I also can get the generic superclass and there I find the type set in extends. But how to bring it together to invoke the method like:

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

ADD: I get the class "StammdataEditFGB" in the composer via Spring by context.getBean(). This construct run in a Spring Context. So also a solution with Spring's ReflectionUtils is very welcome.

Upvotes: 1

Views: 3895

Answers (2)

derlinuxer
derlinuxer

Reputation: 574

Found the solution! There 2 Problems.

1. getDeclaratedMedothod will not find methods there are in extented Classes. By using getMethod you will get methods (methods must be public) in Abstract Classes.
Here a small example to show.

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

Console:

### 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)

After solving that issue there has been the next one with generic type T.

2. The BeanFieldGroup could not be initialized like I did. Of course the beanClass is Null.
Here the solution with setting the beanClass for BeanFieldGroup properly:

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

Now it works!

Upvotes: 1

Priyesh
Priyesh

Reputation: 2071

When you instantiate an object of class StammdataEditFGB, you are already passing the type information to the super class. So, when you call theFGBClass.getClass().getSuperClass(), you will get a AbstractFieldGroupBind class that handles Cinema objects.

Upvotes: 0

Related Questions