Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/322.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用子类作为方法参数调用getMethod_Java_Reflection_Subclass_Invoke_Superclass - Fatal编程技术网

Java 使用子类作为方法参数调用getMethod

Java 使用子类作为方法参数调用getMethod,java,reflection,subclass,invoke,superclass,Java,Reflection,Subclass,Invoke,Superclass,如果argument对象或argument类是一个子类,并且该方法本身将超类作为参数,那么是否可以调用该方法 我试图调用这个方法public void setNewProblem(问题)带有抽象类问题的具体实现。不幸的是,我得到了一个NoSuchMethodException异常 我这样调用调用: Method method = model.getClass().getMethod("set" + propertyName, new Class[] { newValue.getClass() }

如果argument对象或argument类是一个子类,并且该方法本身将超类作为参数,那么是否可以调用该方法

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

我这样调用调用:

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

如果我将
newValue.getClass()
更改为
Problem.class
一切正常。知道如何将子类传递给
public void setNewProblem(问题)

问题在于
newValue.getClass()
是声明方法中类的子类

Class.getMethod

在类C中查找匹配的方法:如果C恰好声明了一个 具有指定名称且形式完全相同的公共方法 参数类型,即反映的方法

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

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

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

但是,我不太愿意提出这个建议,因为它没有涵盖100%的情况(例如,如果形式参数类是一个接口),而且您这样做的方式很糟糕。

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

因此,您可以使用子类进行调用,但在不存在子类的情况下不能请求子类

您可以做的是查看所有方法并找到匹配项


如果您只需要一个属性的setter或getter,我建议您看看哪个可以找到该属性的所有属性和getter/setter方法。

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


该异常不是由invoke()引起的。它是由getMethod()引起的。您需要实际声明的类才能在类中找到方法。但在调用该方法时,可以传递任何子类实例。几乎每次使用反射时,都不应该使用。也许有比反思更好的方法来实现你想要的。您想要实现什么?是的,异常是由getMethod()引起的,可能我不清楚。我使用MVC实现。在这个实现中,控制器使用invoke告诉模型视图中发生了什么变化。问题是我不知道,哪个问题被添加到了模型中。它可能是ProblemX、ProblemY或ProblemZ。@hofmeister您不需要知道它是哪种实例类型,您只需要知道方法的类型。是的,您的权利。ProblemX Problem实例应该足以为getMethod()设置正确的参数?调用setNewProblem(Problem)对于任何问题子类都足够了。你确定你需要反胃吗?也许这是最好的解决办法。更改MVC并扔掉反射。