Java - java.lang.NoSuchMethodException

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19913970/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-12 21:16:08  来源:igfitidea点击:

Java - java.lang.NoSuchMethodException

javainheritancereflectionmethods

提问by Andrius

I try to use this code (Updatem_set is used inside for loop which goes through few methods which use different type arguments. If I would add for example int.class in getMethod, I would get error after one iteration, because next method would require String.class. Is it possible to solve such problem using reflection?):

我尝试使用此代码(更新m_set 在 for 循环中使用,它通过几个使用不同类型参数的方法。如果我添加例如 int.class in getMethod,我会在一次迭代后得到错误,因为下一个方法需要 String .class. 是否可以使用反射来解决此类问题?):

Method m_set = product.getClass().getMethod(method_name);
m_set.invoke(product, method_value);

I get this error:

我收到此错误:

 Exception in thread "main" java.lang.NoSuchMethodException: test.NormalChair.setHeight()
        at java.lang.Class.getMethod(Class.java:1655)
        at test.ProductTrader.create(ProductTrader.java:68)
        at test.Test.main(Test.java:32)

In error it shows that it tries to find method in class that I use this method. But that method is in parent class and it is public method. I know if I would use getDeclaredMethod, it would give similar error, but why it gives this error using getMethod?

错误显示它试图在类中查找我使用此方法的方法。但是该方法在父类中,并且是公共方法。我知道如果我会使用getDeclaredMethod,它会给出类似的错误,但为什么它会使用getMethod?

My class thas has this method:

我的班级有这个方法:

public abstract class AbstractChair {
    public String name;
    public int height;
    public AbstractChair() {
    }

    public AbstractChair(String name, int height){
        this.name = name;
        this.height = height;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getHeight() {
        return height;
    }

    public void setHeight(int height) {
        this.height = height;
    }   
}

My class that I try to use this method on:

我尝试使用此方法的班级:

public class NormalChair extends AbstractChair {
    public NormalChair() {
        super();
    }

    public NormalChair(String name, int height) {
        super(name, height);
    }


    // Copy constructor
    public NormalChair(NormalChair chair) {
      this(chair.getName(), chair.getHeight());
    }

}

Update2

更新2

If I do something like this:

如果我做这样的事情:

if(method_name == "setHeight"){
  Method m_set = product.getClass().getMethod(method_name, int.class);
  m_set.invoke(product, method_value);
}
else if (method_name == "setName")
{
  Method m_set = product.getClass().getMethod(method_name, String.class);
  m_set.invoke(product, method_value);
}

Then error disappears. Can someone suggest more universal approach?

然后错误消失。有人可以建议更通用的方法吗?

采纳答案by Pshemo

It seems that you forgot to pass type of arguments that your method needs (remember that methods can be overloaded with different arguments types). Take a look at your code, there is no setHeight()method there but setHeight(int). You should try something like

您似乎忘记传递方法所需的参数类型(请记住,方法可以使用不同的参数类型重载)。看看你的代码,setHeight()除了setHeight(int). 你应该尝试像

Method m_set = product.getClass().getMethod(method_name,method_value.getClass());
m_set.invoke(product, method_value);


Since you could have problems with primitive types you can use way around. Assuming that there is only one method with same name in your class you want to find you can iterate over all public methods, compare its name with method you are looking for, and then invoke it with arguments you want. Something like

由于您可能会遇到原始类型的问题,因此您可以使用方法。假设您要查找的类中只有一个具有相同名称的方法,您可以遍历所有公共方法,将其名称与您要查找的方法进行比较,然后使用您想要的参数调用它。就像是

Method[] methods = product.getClass().getMethods();
for (Method m : methods){
    System.out.println(m);
    if (m.getName().equals("setHeight")){
        m.invoke(product, method_value);
        break;
    }
}


Another and probably better way would be using classes from java.beanpackage like PropertyDescriptor. Thanks to this class you can find getters and setters for specific property. Notice that property for setHeightis heightso you would need to use it like

另一种可能更好的方法是使用java.beanPropertyDescriptor. 感谢这个类,你可以找到特定属性的 getter 和 setter。请注意,属性 for setHeightisheight所以你需要像这样使用它

Method setter = new PropertyDescriptor("height", product.getClass()).getWriteMethod();
setter.invoke(product, method_value);

回答by sp00m

Use product.getClass().getMethod("setHeight", int.class);. You have to pass the method parameters types to target the method signature.

使用product.getClass().getMethod("setHeight", int.class);. 您必须传递方法参数类型以定位方法签名。