简体   繁体   English

getMethod抛出方法未找到异常

[英]getMethod throws method not found exception

I am using the getMethod(String name, Class[] types) method to get a method but I get a method not found when there is an int parameter. 我正在使用getMethod(String name,Class [] types)方法来获取一个方法,但是当有一个int参数时,我找不到一个方法。 I think I get that because inside my Class array I have the java.lang.Integer class (the wrapper) instead of int. 我想我明白了,因为在我的Class数组中,我有java.lang.Integer类(包装器)而不是int。 I get that class by using a generic Object.getClass() so I don't think I can change that easily. 我通过使用通用的Object.getClass()获得该类,所以我认为我不能轻易更改它。 Here is the part of the code that does this: 这是执行此操作的代码部分:

for (int i = 0; i < parameterTypes.length; i++) {
        parameterTypes[i] = arguments[i].getClass();
}

try {
    Method mmethod = mclass.getMethod(contractName, parameterTypes);
} catch (NoSuchMethodException e) {}

Can I solve this somehow? 我能以某种方式解决吗?

Suppose you have this class 假设你有这个课

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) and setO(Integer i) are two different methods, so you cannot have only one of them in your class and rely on autoboxing to get the method object via Class#getMethod(Class<?>...) and passing one or the other argument type. setO(int i)setO(Integer i)是两个不同的方法,因此您不能在类中只有一个方法,而是依靠自动装箱通过Class#getMethod(Class<?>...)获取方法对象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));
}

will both print 都将打印

set int
set int

and

set Integer
set Integer

Here autoboxing works on invokation. 自动装箱适用于发票。

But in you case you extract the type of the argument from a value which is stored as Object . 但是,在这种情况下,您将从存储为Object的值中提取参数的类型。 In this case primitive types are autoboxed into theire respective wrapper types, hence you do not find a method which corresponds to int.class as argument. 在这种情况下,原始类型会自动装箱到各自的包装器类型中,因此找不到与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));
}

Here the output is: 这里的输出是:

false
set Integer
false
set Integer

As you see, no primitives and only the method with Integer.class is found and called. 如您所见,没有找到任何原语,只有Integer.class的方法被找到和调用。 If you remove it you will get NoSuchMethodException . 如果将其删除,则会得到NoSuchMethodException

So to solve your problem change the method your are trying to invoke via reflection to take a wrapper type or better yet, pass the correct argument types instead of deriving them from some values. 因此,要解决您的问题,请更改您尝试通过反射调用的方法,以采用包装类型或更佳的包装类型,传递正确的参数类型,而不是从某些值中派生它们。

Finally, NoSuchMethodException is also thrown when the method is not accessible ie not public , make sure the method is public. 最后,当无法访问该方法(即不是public ,也会引发NoSuchMethodException ,请确保该方法是公共的。

根据这个问题 ,您应该使用Integer.TYPE引用原始int以进行反射。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM