Java - java.lang.NoSuchMethodException

And*_*ius 2 java reflection methods inheritance

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

Method m_set = product.getClass().getMethod(method_name);
m_set.invoke(product, method_value);
Run Code Online (Sandbox Code Playgroud)

我收到此错误:

 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)
Run Code Online (Sandbox Code Playgroud)

错误地表明它试图在类中找到我使用此方法的方法.但是该方法在父类中,它是公共方法.我知道如果我会使用getDeclaredMethod,它会给出类似的错误,但为什么它会使用这个错误getMethod

我的班级有这种方法:

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;
    }   
}
Run Code Online (Sandbox Code Playgroud)

我尝试使用此方法的类:

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

}
Run Code Online (Sandbox Code Playgroud)

UPDATE2

如果我做这样的事情:

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);
}
Run Code Online (Sandbox Code Playgroud)

然后错误消失.有人可以提出更普遍的方法吗?

Psh*_*emo 9

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

Method m_set = product.getClass().getMethod(method_name,method_value.getClass());
m_set.invoke(product, method_value);
Run Code Online (Sandbox Code Playgroud)

由于你可能遇到基本类型的问题,你可以使用方法.假设您想要在类中只有一个具有相同名称的方法,您可以迭代所有公共方法,将其名称与您要查找的方法进行比较,然后使用您想要的参数调用它.就像是

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

另一种可能更好的方法是使用java.bean类似的包PropertyDescriptor.感谢这个课程,你可以找到特定属性的getter和setter.请注意,属性setHeightheight这样你需要使用它

Method setter = new PropertyDescriptor("height", product.getClass()).getWriteMethod();
setter.invoke(product, method_value);
Run Code Online (Sandbox Code Playgroud)