用一个子类调用getMethod作为方法参数。

时间:2022-08-27 18:46:15

Is it possible to invoke a method where the argument object or the argument class is a subclass and the method himself took the superclass as argument?

是否可以调用一个方法,其中的参数对象或参数类是一个子类,而方法本身将超类作为参数?

I trying to invoke this method public void setNewProblem(Problem problem); with a concrete implementation of the abstract class Problem. Unfortunately I get an NoSuchMethodException exception.

我试图调用这个方法public void setNewProblem(问题问题);通过具体实现抽象类问题。不幸的是,我得到了一个NoSuchMethodException异常。

I call the invoke like this:

我把这样的调用称为:

Method method = model.getClass().getMethod("set" + propertyName, new Class[] { newValue.getClass() });
method.invoke(model, newValue);

If I change newValue.getClass() to Problem.class everything works fine. Any idea how to pass a subclass to public void setNewProblem(Problem problem);?

如果我更改newValue.getClass()到问题。类,一切工作正常。如何将子类传递给public void setNewProblem(问题);?

3 个解决方案

#1


3  

You have to ask for the exact type it is. This is because you can have multiple possible overloaded methods and it needs to know exact what you wanted.

你必须要求准确的类型。这是因为您可以有多个可能的重载方法,并且需要知道您想要的是什么。

So you can invoke with a sub-class but you cannot ask for a sub-class without be being there.

所以你可以调用一个子类,但是你不能要求一个子类没有存在。

What you can do is look at all methods and find a match.

你能做的就是看看所有的方法,找到一根火柴。

If all you need is the setter or getter for a property, I suggest you look at BeanIntrospector which will find you all the properties and the getter/setter methods for that property.

如果您需要的是属性的setter或getter,我建议您查看BeanIntrospector,它将为该属性找到所有属性和getter/setter方法。

#2


1  

The problem is that newValue.getClass() is a subclass of the class in the declared method.

问题是newValue.getClass()是声明方法中类的一个子类。

From Class.getMethod:

从Class.getMethod:

To find a matching method in a class C: If C declares exactly one public method with the specified name and exactly the same formal parameter types, that is the method reflected.

要在类C中找到匹配的方法:如果C声明了一个具有指定名称和完全相同的形式参数类型的公共方法,这就是所反映的方法。

You could work your way up the inheritance chain until it works:

你可以沿着继承链往上走,直到它起作用:

Method getMethod(Class c1, Class c2) {
    if(c2.getSuperClass() == null) {
        return c1.getMethod("set" + propertyName, new Class[] { c2 });
    }
    try {
        return c1.getMethod("set" + propertyName, new Class[] { c2 });
    } catch(NoSuchMethodException e) {
        return getMethod(c1, c2.getSuperClass());
    }
}

Usage:

用法:

Method method = getMethod(model.getClass(), newValue.getClass());

I hesitate to suggest this, however, since it does not cover 100% of cases (such as if the formal argument class is an interface), and the way you are doing this is bad.

但是,我不愿建议这一点,因为它不包括100%的情况(例如,正式的参数类是一个接口),而您这样做的方式是不好的。

#3


1  

When you call Class.getMethod() you have to specify correctly the formal argument types. Not the types of the actual arguments you are planning to supply. You have to match precisely what it says in the declaration of the method concerned.

当您调用Class.getMethod()时,必须正确地指定正式的参数类型。而不是您计划提供的实际参数的类型。你必须精确匹配相关方法声明中的内容。

"The parameterTypes parameter is an array of Class objects that identify the method's formal parameter types, in declared order."

“参数类型参数是一组类对象,它们识别方法的正式参数类型,以声明的顺序。”

#1


3  

You have to ask for the exact type it is. This is because you can have multiple possible overloaded methods and it needs to know exact what you wanted.

你必须要求准确的类型。这是因为您可以有多个可能的重载方法,并且需要知道您想要的是什么。

So you can invoke with a sub-class but you cannot ask for a sub-class without be being there.

所以你可以调用一个子类,但是你不能要求一个子类没有存在。

What you can do is look at all methods and find a match.

你能做的就是看看所有的方法,找到一根火柴。

If all you need is the setter or getter for a property, I suggest you look at BeanIntrospector which will find you all the properties and the getter/setter methods for that property.

如果您需要的是属性的setter或getter,我建议您查看BeanIntrospector,它将为该属性找到所有属性和getter/setter方法。

#2


1  

The problem is that newValue.getClass() is a subclass of the class in the declared method.

问题是newValue.getClass()是声明方法中类的一个子类。

From Class.getMethod:

从Class.getMethod:

To find a matching method in a class C: If C declares exactly one public method with the specified name and exactly the same formal parameter types, that is the method reflected.

要在类C中找到匹配的方法:如果C声明了一个具有指定名称和完全相同的形式参数类型的公共方法,这就是所反映的方法。

You could work your way up the inheritance chain until it works:

你可以沿着继承链往上走,直到它起作用:

Method getMethod(Class c1, Class c2) {
    if(c2.getSuperClass() == null) {
        return c1.getMethod("set" + propertyName, new Class[] { c2 });
    }
    try {
        return c1.getMethod("set" + propertyName, new Class[] { c2 });
    } catch(NoSuchMethodException e) {
        return getMethod(c1, c2.getSuperClass());
    }
}

Usage:

用法:

Method method = getMethod(model.getClass(), newValue.getClass());

I hesitate to suggest this, however, since it does not cover 100% of cases (such as if the formal argument class is an interface), and the way you are doing this is bad.

但是,我不愿建议这一点,因为它不包括100%的情况(例如,正式的参数类是一个接口),而您这样做的方式是不好的。

#3


1  

When you call Class.getMethod() you have to specify correctly the formal argument types. Not the types of the actual arguments you are planning to supply. You have to match precisely what it says in the declaration of the method concerned.

当您调用Class.getMethod()时,必须正确地指定正式的参数类型。而不是您计划提供的实际参数的类型。你必须精确匹配相关方法声明中的内容。

"The parameterTypes parameter is an array of Class objects that identify the method's formal parameter types, in declared order."

“参数类型参数是一组类对象,它们识别方法的正式参数类型,以声明的顺序。”