最近研究jetty源代碼的時候,發(fā)現(xiàn)這個容器里面的代碼根本無法看懂,都是java語法,基本上都是反射+設(shè)計模式+配置文件。很莫名奇妙的方法調(diào)用。里面有調(diào)用main方法的反射,結(jié)果沒看懂,所以就再來研究研究反射功能。由于反射的文章在網(wǎng)上太多了,我主要研究了一下main方法,private方法的調(diào)用。如下,反射調(diào)用HelloWorld類的方法。HelloWorld類如下:
   
public class HelloWorld { 
    public static void main(String[] args) {
        System.out.println("HelloWorld");
    }
    private void prt(String msg){
        System.out.println(msg);
    }
}
  
     調(diào)用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[]{});
    }
}
     調(diào)用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");
            }
        }
    }
}
     總結(jié):
            1 調(diào)用main方法需要注意,main方法的參數(shù)為String[],但是在method.invoke時,需要將String[]強制轉(zhuǎn)換為Object,至于原因,網(wǎng)上很多說這個,主       要是說jdk執(zhí)行main方法時要將String[]分成多個參數(shù)等等。后續(xù)我分析了源代碼后,會將這個問題專門寫個文章出來。
            2 調(diào)用private方法需要注意,在調(diào)用此方法之前,需要將此執(zhí)行的方法設(shè)置以下,而不是隨便找個地方運行下method.setAccessible(true)就完事了。
            3 使用反射動態(tài)調(diào)用方法時,主要是用method.invoke()方法,如果是靜態(tài)方法,則invoke的第一個參數(shù)設(shè)置null,如果不是靜態(tài)方法,則將第一個參數(shù)設(shè)      置為該類生成的對象即可。