java反射调用main方法踩坑
时间:2021-06-24 17:56:28
收藏:0
阅读:0
被调用类
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数组包装一下。
评论(0)