【问题标题】:Why does Class#getDeclaredMethods0 fail when trying to invoke main?为什么尝试调用 main 时 Class#getDeclaredMethods0 失败?
【发布时间】:2015-03-03 23:20:11
【问题描述】:

为什么这段代码 sn-p 失败并显示IllegalArgumentException: wrong number of arguments?演示代码适用于普通成员和静态方法,以及原生声明的方法...

   public class Program {
        public static void main(String[] args) throws ReflectiveOperationException {
            //get native getDeclaredMethods method
            Method Class$getDeclaredMethods0 = Class.class.getDeclaredMethod("getDeclaredMethods0", boolean.class);
            Class$getDeclaredMethods0.setAccessible(true);

            //call main
            Method[] methods = (Method[]) Class$getDeclaredMethods0.invoke(Program.class, false);
            Method main = methods[0];
            main.invoke(null, args); // ← Exception in thread "main" java.lang.IllegalArgumentException: wrong number of arguments
            //at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            //at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
            //at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
            //at java.lang.reflect.Method.invoke(Method.java:606)
            //at Program.main(Program.java:19)
            //at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
            //at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57)
            //at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
            //at java.lang.reflect.Method.invoke(Method.java:606)
            //at com.intellij.rt.execution.application.AppMain.main(AppMain.java:134)
        }
    }

【问题讨论】:

  • 你为什么要通过反射而不是直接调用getDeclaredMethods?为什么你假设只有一个声明的方法,必须是main
  • 作为补充——如何将静态初始化器、实例初始化器和默认构造器作为方法返回?
  • 每个帖子一个问题,拜托。 (是什么让您认为这些是可用的 as 方法?)
  • 构造函数被实现为方法(在我看来它们是一个糟糕的设计选择),而初始化程序是可执行代码。它们具有需要作为方法处理的各个方面 - 名称、偏移量、可见性、父对象
  • “构造函数被实现为方法”——在什么意义上? (这里有很多可能的含义。)反射允许您直接访问构造函数,那么为什么不这样做呢?至于实例初始值设定项 - 它们没有有名称,它们实际上已融入到每个构造函数中。

标签: java reflection


【解决方案1】:

不清楚你为什么要通过反射调用getDeclaredMethods,但是main 的调用被破坏了,因为你试图调用它,就好像它有几个String 参数——@987654324 中的每个值一个@。相反,您想传递一个String[] 类型的single 参数。你可以这样做:

main.invoke(null, new Object[] { args });

【讨论】:

  • 它有效,但String[] 不是Object... - 那么为什么需要放置new Object[]{...} 呢?是协变/逆变吗?
  • @BinkanSalaryman:是的,它是一个Object[]。试试看:Object[] x = new String[10];。这就是你的数组协方差。 (Object... 并不是真正的类型 - 它只是 Object[] 带有一个标志,上面写着“这个参数是可变参数......”)
猜你喜欢
  • 2012-12-17
  • 2017-03-27
  • 1970-01-01
  • 1970-01-01
  • 2018-11-30
  • 2022-01-24
  • 2010-12-07
  • 2019-08-06
  • 1970-01-01
相关资源
最近更新 更多