java反射调用main方法踩坑
被调用类
import java.util.Arrays;
public class TestMain {
  public static void main(String[] args) {
    System.out.println("TestMain");
  }
  public static void testA(String... names) {
    System.out.println("testA: " + Arrays.toString(names));
  }
  public void testB(String[] names) {
    System.out.println("testB: " + Arrays.toString(names));
  }
  public void testC(String... names) {
    System.out.println("testC: " + Arrays.toString(names));
  }
  public void testD(Object... objects) {
    System.out.println("testD: " + Arrays.toString(objects));
  }
}
调用类
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
public class Client2 {
  public static void main(String[] args)
      throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
    Class<TestMain> aClass = TestMain.class;
    Method mainMethod = aClass.getDeclaredMethod("main", String[].class);
    //错误
    //mainMethod.invoke(null, new String[]{});
    //第一种方法
    mainMethod.invoke(null, (Object) new String[]{});
    //第二种方法
    mainMethod.invoke(null, new Object[]{new String[]{}});
    Method testAMethod = aClass.getDeclaredMethod("testA", String[].class);
    testAMethod.invoke(null, (Object) new String[]{"a"});
    Method testBMethod = aClass.getDeclaredMethod("testB", String[].class);
    testBMethod.invoke(new TestMain(), (Object) new String[]{"b"});
    Method testCMethod = aClass.getDeclaredMethod("testC", String[].class);
    testCMethod.invoke(new TestMain(), (Object) new String[]{"c"});
    //解析成多个参数
    new TestMain().testD(new String[]{"d", "e"});
    //解析成一个参数
    new TestMain().testD((Object) new String[]{"d", "e"});
  }
}
输出为
TestMain
TestMain
testA: [a]
testB: [b]
testC: [c]
testD: [d, e]
testD: [[Ljava.lang.String;@6c3708b3]
反射调用静态方法时,第一个参数为 null,当参数类型为数组或可变参数时,调用时必须将数组类型转换为Object
(Object) new String[]{}
或使用Object数组包装一层
new Object[]{new String[]{}}
不然会报错,参数类型不匹配
Exception in thread "main" java.lang.IllegalArgumentException: argument type mismatch
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
	at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
	at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
	at java.base/java.lang.reflect.Method.invoke(Method.java:566)
	at com.imooc.sourcecode.java.javacompile.test5.Client2.main(Client2.java:17)
这是因为jdk1.4和1.5中的Method类设计有区别,1.4如下
public Object invoke(Object obj, Object[] args)
1.5如下
public Object invoke(Object obj, Object... args)
参数类型从数组变成了可变参数,如果直接传递new String[]{}参数,jdk1.4下会转换成多个参数,jdk1.5下是一个参数,jdk会向下兼容1.4,我们为了让编译器正确的解析参数,需要做上述两种转换,转换为 Object,或使用 Object数组包装一下。
 
         
         
         
         
         
        
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号