看下,反射中可能遇到的一个问题:
一个类,专门用来进行测试反射相关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);