如何从泛型类型的抽象类调用方法(使用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;
}
}