天天看點

反射取含數組的構造函數時的參數類型傳遞

今天在和瑾華讨論ASM的時候,通過将反射的method轉換為asm的method時遇到反射時數組的問題。當時兩個人都卡住了,現在實驗通了,順手記錄下來。

原始類:

public class Person implements China { 

    protected String name; 

    public Person(String name) { 

        this.name = name; 

    } 

    public Person(String name1[],String name2) { 

    public String sayHello(String name) { 

        return "welcome " + name; 

    protected void protect() { 

        privatedMethod(); 

    private void privatedMethod() { 

通過反射取得構造函數, 通常的方法為:

@Test 

    public void test04() { 

        try { 

            Class<?> clazz = (Class<?>) Class 

                    .forName("com.alibaba.demoeo.reflect.classes.Person"); 

            Constructor<?>[] constructs = clazz.getConstructors(); 

            for (Constructor<?> construct : constructs) { 

                System.out.println(construct.getName()); 

            } 

        } catch (Exception e) { 

            e.printStackTrace(); 

        } 

如果要取得特定參數的構造函數,則為:

    public void test07() { 

            .forName("com.alibaba.demoeo.reflect.classes.Person"); 

            Constructor<?> construct = clazz.getConstructor(String.class); 

            System.out.println(construct); 

問題引出:而要取得含有數組的參數的構造函數如何辦呢? 這也是我們卡住的原因,實驗了clazz.getConstructor(String.class, String.class); clazz.getConstructor(Array.class, String.class);等都不行, 後來通過反射機制将參數類型輸出進行檢視,發現數組為:class [Ljava.lang.String;

public void test05() { 

    try { 

        Class<?> clazz = (Class<?>) Class 

        .forName("com.alibaba.demoeo.reflect.classes.Person"); 

        Constructor<?>[] constructs = clazz.getConstructors(); 

        for (Constructor<?> construct : constructs) { 

            Class<?>[] types = construct.getParameterTypes(); 

            for(Class<?> type : types){ 

                System.out.println(type); 

            System.out.println("-------------"); 

    } catch (Exception e) { 

        e.printStackTrace(); 

輸出為:

class java.lang.String 

------------- 

class [Ljava.lang.String; 

好的,現在知道是什麼内容了,那就使用這種類型來構造:

    public void test06() { 

            Constructor<?> construct = clazz.getConstructor(Class.forName(("[Ljava.lang.String;")), String.class); 

測試結果正确,輸出如下:

public com.alibaba.demoeo.reflect.classes.Person(java.lang.String[],java.lang.String) 

考慮getConstructor的參數為可變數組,于是考慮通過傳遞數組類型給getConstructor方法,經測試後通過,具體如下:

    public void test08() { 

            Constructor<?> construct = clazz.getConstructor(new Class[]{String[].class,String.class}); 

使用此方法測試ASM轉換:

public class Demo { 

    public void test(String[] str){} 

    /** 

     * @param args 

     */ 

    public static void main(String[] args) throws Exception{ 

        java.lang.reflect.Method method = Demo.class.getMethod("test", Class.forName("[Ljava.lang.String;")); 

        //java.lang.reflect.Method method = Demo.class.getMethod("test", new Class[]{String[].class}); 

        com.alibaba.citrus.asm.commons.Method asmMethod = com.alibaba.citrus.asm.commons.Method.getMethod(method); 

        System.out.println(asmMethod.getDescriptor()); 

或者

        //java.lang.reflect.Method method = Demo.class.getMethod("test", Class.forName("[Ljava.lang.String;")); 

        java.lang.reflect.Method method = Demo.class.getMethod("test", new Class[]{String[].class}); 

測試結果:

([Ljava/lang/String;)V 

【注意】

1、今天讨論之後,也可以使用String[].class表達字元串數組也是可以的

本文轉自 tianya23 51CTO部落格,原文連結:http://blog.51cto.com/tianya23/568119,如需轉載請自行聯系原作者