Java反射getMethod给出异常

时间:2016-04-17 09:02:03

标签: java reflection

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

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

public class 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)

2 个答案:

答案 0 :(得分:3)

基本上,您的参数值已自动生成其Object等效项(intInteger),这意味着反射API正在寻找一个形式参数为{{{ 1}},它显然无法找到

但是,如果我将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});

&#34; main&#34;因为我以这种方式接近它,过去,我浪费了很多时间来追逐哪个参数/值对破坏了,并且使用构建器更容易阅读和理解这种模式,但那只是我。

我也在寻找除了使用反射之外的任何其他解决方案,它有它的位置并可以做很多事情,但它并不是一个真正可靠的长期解决方案,尤其是当您需要重构代码时

答案 1 :(得分:0)

问题是你的方法需要taras@t626:~$ dig parkan.trade +nostats +nocomments +nocmd ; <<>> DiG 9.9.5-3ubuntu0.8-Ubuntu <<>> parkan.trade +nostats +nocomments +nocmd<br/> ;; global options: +cmd ;parkan.trade. IN A parkan.trade. 45 IN A 104.28.8.106 parkan.trade. 45 IN A 104.28.9.106 parkan.trade. 6945 IN NS SKIP.NS.CLOUDFLARE.COM. parkan.trade. 6945 IN NS TRICIA.NS.CLOUDFLARE.COM. SKIP.NS.CLOUDFLARE.COM. 26515 IN A 173.245.59.233 SKIP.NS.CLOUDFLARE.COM. 171614 IN AAAA 2400:cb00:2049:1::adf5:3be9 TRICIA.NS.CLOUDFLARE.COM. 32805 IN A 173.245.58.232 TRICIA.NS.CLOUDFLARE.COM. 42485 IN AAAA 2400:cb00:2049:1::adf5:3ae8 类型(基元)但是你正在使用int类型(非基元)搜索一个方法,这是两个不同的东西,因此无法找到它。您搜索非基元的原因是Integerfrom的类型。尝试将它们更改为des,可能还必须更改int的签名以适合参数。