java反射调用main方法,private方法实现

时间:2021-08-04 21:27:21

最近研究jetty源代码的时候,发现这个容器里面的代码根本无法看懂,都是java语法,基本上都是反射+设计模式+配置文件。很莫名奇妙的方法调用。里面有调用main方法的反射,结果没看懂,所以就再来研究研究反射功能。由于反射的文章在网上太多了,我主要研究了一下main方法,private方法的调用。如下,反射调用HelloWorld类的方法。HelloWorld类如下:

public class HelloWorld { 
    public static void main(String[] args) {
        System.out.println("HelloWorld");
    }
    private void prt(String msg){
        System.out.println(msg);
    }
}

调用main方法如下:

public class HelloWorldRefection { 
    public static void main(String[] args) throws InstantiationException, IllegalAccessException, 
        SecurityException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException {
        Method method = HelloWorld.class.getMethod("main",String[].class);
        method.invoke(null,(Object)new String[]{});
    }
}

调用private方法如下:

public class HelloWorldRefection { 
    public static void main(String[] args) throws InstantiationException, IllegalAccessException, 
    SecurityException, NoSuchMethodException, IllegalArgumentException, InvocationTargetException {
        Class clazz = HelloWorld.class;
        HelloWorld helloworld = HelloWorld.class.newInstance();
        Method[] methods = clazz.getDeclaredMethods();
        for (Method method : methods) {
            System.out.println(method.getName());
            if(method.getName().equals("prt")){
                method.setAccessible(true);
                method.invoke(helloworld, "hello");
            }
        }
    }
}

 总结:
            1 调用main方法需要注意,main方法的参数为String[],但是在method.invoke时,需要将String[]强制转换为Object,至于原因,网上很多说这个,主要是说jdk执行main方法时要将String[]分成多个参数等等。后续我分析了源代码后,会将这个问题专门写个文章出来。
            2 调用private方法需要注意,在调用此方法之前,需要将此执行的方法设置以下,而不是随便找个地方运行下method.setAccessible(true)就完事了。
            3 使用反射动态调用方法时,主要是用method.invoke()方法,如果是静态方法,则invoke的第一个参数设置null,如果不是静态方法,则将第一个参数设置为该类生成的对象即可。