Java反射getMethod给出异常

标签 java reflection

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

最短路径算法.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

公共(public)类 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反射getMethod给出异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36674584/

相关文章:

Java 密码搜索字符

java - 警告 : Attempt to convert JsonElement from GSON. 此功能已弃用。 Selenium 跟踪诊断堆栈跟踪

java - getActualTypeArguments 与父级,从子级获取其参数化类型

c# - 确定 MethodInfo 是否表示 lambda 表达式

java - 如何通过字符串名称获取类引用?

java - 如何使用 JasperReports 导出 CSV

java - Logger.setLevel() 无法正确启用日志记录

java - 当输入 'q'时结束java程序

C# 使用 Activator.CreateInstance

c# - 在请求上使用反射使w3wp.exe进程崩溃