Java - java.lang.NoSuchMethodException

标签 java inheritance reflection methods

我尝试使用此代码(更新 m_set 在 for 循环内部使用,该循环经历了几种使用不同类型参数的方法。如果我在 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)

错误表明它尝试在我使用此方法的类中查找方法。但该方法位于父类中,并且是公共(public)方法。我知道我是否会使用 getDeclaredMethod ,它会给出类似的错误,但为什么它使用 getMethod 给出此错误?

我的类(class)有这个方法:

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

我尝试使用此方法的类(class):

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);
<小时/>

由于您可能会遇到原始类型的问题,因此您可以使用其他方法。假设您要查找的类中只有一个同名方法,您可以迭代所有公共(public)方法,将其名称与您要查找的方法进行比较,然后使用所需的参数调用它。类似的东西

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。通过这个类,您可以找到特定属性的 getter 和 setter。请注意,setHeight 的属性是 height,因此您需要像

那样使用它
Method setter = new PropertyDescriptor("height", product.getClass()).getWriteMethod();
setter.invoke(product, method_value);

关于Java - java.lang.NoSuchMethodException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19913970/

相关文章:

Java 继承 - 当对派生对象使用基变量时,基类方法被派生类覆盖

c++ - 调用派生类的函数调用操作符时避免使用指针

java - 如何生成由列表支持的 map

java - 为什么使用 jarsigner 进行 apk 签名会给出 java.security.NoSuchAlgorithmException : SHA11 MessageDigest not available?

java - 尝试使用 SAXParser 解析 Android 应用程序中的 XML

javascript - 为什么我的继承不起作用?

class - 在 Dart 中,使用 Mirrors,如何从类的实例调用类的静态方法?

reflection - 我可以在 Go 中使用反射创建一个新函数吗?

android - Kotlin 反射的 ProGuard 规则

java - 在Android应用程序中定义位图的大小