Java反射getMethod给出异常

Java反射getMethod给出异常,java,reflection,Java,Reflection,我得到了“java.lang.NoSuchMethodException”,尽管我可以在classType.getMethods()中看到我的方法;请帮忙 ShortestPathAlgorithm.java SPATest.java RunWithTimeTrace.java 公共类RunWithTimeTrace{ public static void run(Class<?> classType, String methodName, Object... paramVa

我得到了“java.lang.NoSuchMethodException”,尽管我可以在classType.getMethods()中看到我的方法;请帮忙

ShortestPathAlgorithm.java SPATest.java RunWithTimeTrace.java 公共类RunWithTimeTrace{

    public static void run(Class<?> classType, String methodName, Object... paramValues ){

        try{
            Object o = classType.newInstance();
            int n = paramValues.length;
            Class<?>[] arr = new Class[n];
            for(int i=0; i < n; i++){
                arr[i] = paramValues[i].getClass();
            }

            Method[] declaredMethods = classType.getMethods();
            System.out.println(Arrays.toString(declaredMethods));

            System.out.println("------------------------");

            Method method = classType.getDeclaredMethod(methodName, arr);
            long s = System.currentTimeMillis();
            method.invoke(o, paramValues);
            long t = System.currentTimeMillis();
            System.out.println("Time Taken : " + (t - s));
        }catch(Exception e){
            e.printStackTrace();
        }

    }

}

基本上,您的参数值被自动装箱到它们的
对象
等价物(
int
Integer
),这意味着反射API正在寻找一个具有
Integer[][],Integer,Integer
形式参数的方法,它显然找不到

但是,如果我将您的
run
方法更改为

public static void run(Class<?> classType, String methodName, Object[] paramValues, Class[] types) {

    try {
        Object o = classType.newInstance();
        int n = paramValues.length;

        Method[] declaredMethods = classType.getMethods();
        System.out.println(Arrays.toString(declaredMethods));

        System.out.println("------------------------");

        Method method = classType.getDeclaredMethod(methodName, types);
        long s = System.currentTimeMillis();
        method.invoke(o, paramValues);
        long t = System.currentTimeMillis();
        System.out.println("Time Taken : " + (t - s));
    } catch (Exception e) {
        e.printStackTrace();
    }

}
它起作用了

就我个人而言,我会将很多内容封装到某个类型的类中,这样您不仅可以指定参数值,还可以在单个调用中指定它的类型

Runner runner = new Runner(ShortestPathAlgorithm.class)
                        .execute("show")
                        .withParameter(int[][].class, graph)
                        .withParameter(int.class, from)
                        .withParameter(int.class, des);
runner.run();
我采用这种方法的“主要”原因是,在过去,我浪费了很多时间寻找哪个参数/值对损坏了,并且以这种方式使用构建器模式更容易阅读和理解,但这只是我自己


除了使用反射之外,我还想寻找其他任何解决方案,它有它的位置,可以做很多事情,但它不是一个真正可靠的长期解决方案,特别是当您需要重构代码时。问题是您的方法需要
int
类型(原语)但是您正在使用
Integer
type(非原语)搜索方法,这是两个不同的东西,因此无法找到。搜索非原语的原因是
from
des
的类型。尝试将它们更改为
int
,可能是
RunWithTimeTrace的签名。run
也必须更改以适应参数。

两者之间存在差异
int
Integer
,您的vararg已自动装箱到其等效类型
[public void demo.ds.graph.main.ShortestPathAlgorithm.show(int[][],int,int), public final void java.lang.Object.wait() throws java.lang.InterruptedException, public final void java.lang.Object.wait(long,int) throws java.lang.InterruptedException, public final native void java.lang.Object.wait(long) throws java.lang.InterruptedException, public boolean java.lang.Object.equals(java.lang.Object), public java.lang.String java.lang.Object.toString(), public native int java.lang.Object.hashCode(), public final native java.lang.Class java.lang.Object.getClass(), public final native void java.lang.Object.notify(), public final native void java.lang.Object.notifyAll()]
------------------------
java.lang.NoSuchMethodException: demo.ds.graph.main.ShortestPathAlgorithm.show([[I, java.lang.Integer, java.lang.Integer)
    at java.lang.Class.getDeclaredMethod(Class.java:2130)
    at demo.ds.graph.test.RunWithTimeTrace.run(RunWithTimeTrace.java:23)
    at demo.ds.graph.test.SPATest.main(SPATest.java:20)
public static void run(Class<?> classType, String methodName, Object[] paramValues, Class[] types) {

    try {
        Object o = classType.newInstance();
        int n = paramValues.length;

        Method[] declaredMethods = classType.getMethods();
        System.out.println(Arrays.toString(declaredMethods));

        System.out.println("------------------------");

        Method method = classType.getDeclaredMethod(methodName, types);
        long s = System.currentTimeMillis();
        method.invoke(o, paramValues);
        long t = System.currentTimeMillis();
        System.out.println("Time Taken : " + (t - s));
    } catch (Exception e) {
        e.printStackTrace();
    }

}
run(ShortestPathAlgorithm.class, "show", new Object[]{graph, from, des}, new Class[]{int[][].class, int.class, int.class});
Runner runner = new Runner(ShortestPathAlgorithm.class)
                        .execute("show")
                        .withParameter(int[][].class, graph)
                        .withParameter(int.class, from)
                        .withParameter(int.class, des);
runner.run();