java 反射 method invoke 變長參數

看下,反射中可能遇到的一個問題:

一個類,專門用來進行測試反射相關code:

public class InvokeClass {

    private final static String TAG = "InvokeClassDemo";


    public void printString(String... args) {
        Log.d(TAG, "args len: " + ((args == null) ? "null" : args.length));
    }


    public void printStringTwoArgs(String key, String[] args) {
        Log.d(TAG, "args len: " + ((args == null) ? "null" : args.length));
    }


    public void testPrintString() {
        printString(new String[2]);
    }
}

在主actiivty中調用反射。

注意:第一個方法printString的參數是變長的。第二個方法printStringTwoArgs第二個參數也是變長的,不同的是,它有兩個參數;

然而就這點區別,造成了反射調用時的不同。這裏要get的點:一個可變參數時,反射調用的時候會拆解參數;兩個參數的時候不會進行拆解。

拿到方法:

invokePrintString = invokeClass.getMethod("printString", String[].class);
invokePrintStringTwoArgs =  invokeClass.getMethod("printStringTwoArgs", String.class, String[].class);
ivokeTestPrintString = invokeClass.getMethod("testPrintString");

進行反射調用:

第一個方法中,會出現crash,用註釋標註了:

if (invokePrintString != null) {
                    invokePrintString.invoke(a, new String[1]);
                    invokePrintString.invoke(a, (Object) new String[]{"a", "b"});

                    // crash:Caused by: java.lang.IllegalArgumentException: Wrong number of arguments; expected 1, got 2
//                    invokePrintString.invoke(a, new String[2]);
                    // IllegalArgumentException: method shixin398.invokedemo.InvokeClass.printString argument 1 has type java.lang.String[], got java.lang.String
//                    invokePrintString.invoke(a, new String[] {"a"});
//                    invokePrintString.invoke(a, new String[] {"a","b"});
                }

第二個就沒有問題,兩個參數,就不會拆解。

if (invokePrintStringTwoArgs != null) {
    invokePrintStringTwoArgs.invoke(a,"b", new String[1]);
    invokePrintStringTwoArgs.invoke(a,"b", (Object) new String[]{"a", "b"});
    invokePrintStringTwoArgs.invoke(a,"b", new String[2]);
    invokePrintStringTwoArgs.invoke(a,"b", new String[] {"a"});
    invokePrintStringTwoArgs.invoke(a,"b", new String[] {"a","b"});
}

同樣,直接invoke第三個沒有參數的方法,直接調用,是ok的。不會報錯。

ivokeTestPrintString.invoke(a);
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章