Reputation: 574
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
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
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