getMethod抛出方法未找到异常

时间:2015-08-01 11:58:46

标签: java reflection

我使用getMethod(String name,Class [] types)方法来获取方法,但是当有一个int参数时,我得到一个找不到的方法。我想我得到了,因为在我的Class数组中我有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) {}

我能以某种方式解决这个问题吗?

2 个答案:

答案 0 :(得分:2)

假设你有这个类

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

这里的autoboxing适用于invokation。

但是在你的情况下,你从一个存储为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,请确保该方法是公开的。

答案 1 :(得分:0)

根据this question,您应该使用Integer.TYPE来引用原始int以进行反思。