看下,反射中可能遇到的一個問題:
一個類,專門用來進行測試反射相關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);