看下,反射中可能遇到的一个问题:

一个类,专门用来进行测试反射相关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);