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

ShortestPathAlgorithm.java

public class ShortestPathAlgorithm {

    public void show(int[][] graph, int from, int des){

          // some complex code :D
    }
}


SPATest.java

public class SPATest {
    public static void main(String[] args) {

         int graph[][] = {
                    {0, 1, 5, 4, 0},
                    {1, 0, 0, 2, 4},
                    {5, 0, 0, 1, 0},
                    {4, 2, 1, 0, 1},
                    {0, 4, 0, 1, 0},
                };

         Integer from = 1;
         Integer des = 2;


         RunWithTimeTrace.run(ShortestPathAlgorithm.class, "show", graph, from, des);

    }
}


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

    }

}


我可以在getMethods中看到我的方法,但不能在反射中看到。为什么??

输出:

[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)

最佳答案

基本上,您的参数值会自动装箱到它们的Object等效项(intInteger),这意味着反射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();
    }

}


然后用

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();


我采用这种方式的“主要”原因是在过去,我浪费了很多时间来寻找哪个参数/值对中断,并且以这种方式使用构建器模式更容易阅读和理解,但那只是我。

除了使用反射之外,我还将寻找几乎所有其他解决方案,它有它的位置并且可以做很多事情,但这并不是一个可靠的长期解决方案,尤其是当您需要重构代码时

关于java - Java反射getMethod给出异常,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/36674584/

10-14 20:23