getMethod抛出方法未找到异常



我使用getMethod(字符串名称,类[]类型)方法来获取方法,但当有一个int参数时,我得到一个未找到的方法。我想我得到了,因为在我的类数组中,我有java.lang.Integer类(包装器)而不是int。我通过使用泛型Object.getClass()来获得那个类,所以我认为我不能轻易改变它。下面是这部分代码:

for (int i = 0; i < parameterTypes.length; i++) {
        parameterTypes[i] = arguments[i].getClass();
}
try {
    Method mmethod = mclass.getMethod(contractName, parameterTypes);
} catch (NoSuchMethodException e) {}

我能解决这个问题吗?

假设你有这样一个类

class ReflectTest {
    Object o = null;
    public void setO(int i) {
        System.out.println("set int");
        o = i;
    }
    public void setO(Integer i) {
        System.out.println("set Integer");
        o = i;
    }
}

setO(int i)setO(Integer i)是两个不同的方法,所以你不能在你的类中只有一个方法,并依靠自动装箱通过Class#getMethod(Class<?>...)获得方法对象并传递一个或另一个参数类型。

@Test
public void invoke() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
    Method method = ReflectTest.class.getMethod("setO", int.class);
    method.invoke(new ReflectTest(), 3);
    method.invoke(new ReflectTest(), Integer.valueOf(3));
    method = ReflectTest.class.getMethod("setO", Integer.class);
    method.invoke(new ReflectTest(), 3);
    method.invoke(new ReflectTest(), Integer.valueOf(3));
}

将同时打印

set int
set int

set Integer
set Integer

这里自动装箱在调用中起作用。

但是在您的情况下,您从存储为Object的值中提取参数的类型。在这种情况下,原始类型被自动装箱到它们各自的包装类型中,因此您找不到对应于int.class作为参数的方法。

@Test
public void invoke() throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
    invoke(new ReflectTest(), "setO", 3);
    invoke(new ReflectTest(), "setO", Integer.valueOf(3));
}
private void invoke(Object instance, String methodeName, Object argValue) throws NoSuchMethodException, SecurityException, IllegalAccessException, IllegalArgumentException, InvocationTargetException {
    System.out.println(argValue.getClass().isPrimitive());
    Method method = ReflectTest.class.getMethod("setO", argValue.getClass());
    method.invoke(new ReflectTest(), argValue);
    method.invoke(new ReflectTest(), Integer.valueOf(3));
}

这里的输出是:

false
set Integer
false
set Integer

如您所见,没有发现并调用原语,只有具有Integer.class的方法。如果你删除它,你会得到NoSuchMethodException

所以要解决你的问题,改变你试图通过反射调用的方法,采用包装器类型,或者更好的是,传递正确的参数类型,而不是从一些值派生它们。

最后,当方法不可访问时,也会抛出NoSuchMethodException,即不是public,确保该方法是公共的。

根据这个问题,出于反射的目的,您应该使用Integer.TYPE来引用原语int

相关内容

  • 没有找到相关文章

最新更新