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

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


我收到此错误:

 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)


错误显示它试图在我使用此方法的类中查找方法。但是该方法在父类中,并且是公共方法。我知道是否要使用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;
    }
}


我尝试在以下类上使用此方法的班级:

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

}


更新2

如果我做这样的事情:

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


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

最佳答案

似乎您忘记了传递方法需要的参数类型(请记住,方法可以重载不同的参数类型)。看一下您的代码,那里只有setHeight(),没有setHeight(int)方法。你应该尝试像

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




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

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




另一种可能更好的方法是使用java.bean包中的类,例如PropertyDescriptor。通过此类,您可以找到特定属性的获取器和设置器。请注意,setHeight的属性为height,因此您需要像

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

10-04 17:46