文章目录

1.概述
因为要Java反射调用可变参数的方法,所以参考了这篇文章:https://www.cnblogs.com/huqingchen/p/5979936.html
但是测试过程中,有一点我不明白,就是反射调用可变参数的方法时,为什么一定要保证传入的参数数组长度为1
,
然后如下
package com.java.reflect.demo;
public class BaseObject {
public void getObjectName() {
System.out.println("BaseObject");
}
}
package com.java.reflect.demo;
public class SubObject extends BaseObject {
@Override
public void getObjectName() {
System.out.println("SubObject");
}
public void getParamsLength(String... params) {
System.out.println("param's length is:" + params.length);
}
public void getParamsLength(String param1, String param2) {
System.out.println(param1 + "-" + param2);
}
}
测试类如下
package com.java.reflect.demo;
import org.junit.Assert;
import org.junit.Test;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import static org.junit.Assert.*;
public class ReflectToMulityParamsMethosTest {
private static final String BASE_OBJECT_PATH = "com.java.reflect.demo.BaseObject";
private static final String SUB_OBJECT_PATH = "com.java.reflect.demo.SubObject";
/**
* 测试点:测试反射调用可变参数的方法
*/
@Test
public void reflectToMulityParamsMethosTest1() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
Class sClazz = Class.forName(SUB_OBJECT_PATH);
Object sObj = sClazz.newInstance();//子类实例
//2.反射调用可变参数的方法
Method changeMethod = sClazz.getDeclaredMethod("getParamsLength", String[].class);
//可变参数必须这样封装,因为java反射内部实现做了参数个数为1的判断,如果参数长度不为1,则会抛出异常
String[] strParams = {"a","b","c"};
Object[] cParams = {strParams};
changeMethod.invoke(sObj, cParams);
}
/**
* 测试点:
* 参数为 1
*
* 运行如下
* 0
* 1
* @throws ClassNotFoundException
* @throws IllegalAccessException
* @throws InstantiationException
* @throws NoSuchMethodException
* @throws InvocationTargetException
*/
@Test
public void reflectToMulityParamsMethosTest2() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
Class sClazz = Class.forName(SUB_OBJECT_PATH);
Object sObj = sClazz.newInstance();//子类实例
//2.反射调用可变参数的方法
Method changeMethod = sClazz.getDeclaredMethod("getParamsLength", String[].class);
//可变参数必须这样封装,因为java反射内部实现做了参数个数为1的判断,如果参数长度不为1,则会抛出异常
String[] strParams = {};
System.out.println(strParams.length);
Object[] cParams = {strParams};
System.out.println(cParams.length);
changeMethod.invoke(sObj, cParams);
}
/**
* 测试点:这个与上面差了一点点,然后一个报错 一个不报错
* 这里离的参数个数为0,上面的参数个数为1
* @throws ClassNotFoundException
* @throws IllegalAccessException
* @throws InstantiationException
* @throws NoSuchMethodException
* @throws InvocationTargetException
*/
@Test
public void reflectToMulityParamsMethosTest3() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
Class sClazz = Class.forName(SUB_OBJECT_PATH);
Object sObj = sClazz.newInstance();//子类实例
//2.反射调用可变参数的方法
Method changeMethod = sClazz.getDeclaredMethod("getParamsLength", String[].class);
//可变参数必须这样封装,因为java反射内部实现做了参数个数为1的判断,如果参数长度不为1,则会抛出异常
Object[] cParams = {};
System.out.println(cParams.length);
changeMethod.invoke(sObj, cParams);
}
/**
* 测试点:测试反射调用可变参数的方法
*/
@Test
public void reflectToMulityParamsMethosTest() throws ClassNotFoundException, IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
Class bClazz = Class.forName(BASE_OBJECT_PATH);
Class sClazz = Class.forName(SUB_OBJECT_PATH);
Object bObj = bClazz.newInstance();//父类实例
Object sObj = sClazz.newInstance();//子类实例
// 1.反射调用子类父类的重载方法
// 多态+动态绑定
Method bMethod = bClazz.getDeclaredMethod("getObjectName");
bMethod.invoke(bObj);//父类的bMethod调用父类的getObjectName()
bMethod.invoke(sObj);//父类的bMethod调用子类的getObjectName();
Method sMethod = sClazz.getDeclaredMethod("getObjectName");
//不符合多态和动态绑定
// sMethod.invoke(bObj);//sMethod调用父类的getObjectName(),会报错:java.lang.IllegalArgumentException: object is not an instance of declaring class
sMethod.invoke(sObj);
//2.反射调用可变参数的方法
Method changeMethod = sClazz.getDeclaredMethod("getParamsLength", String[].class);
//可变参数必须这样封装,因为java反射内部实现做了参数个数为1的判断,如果参数长度不为1,则会抛出异常
String[] strParams = {"a","b","c"};
Object[] cParams = {strParams};
changeMethod.invoke(sObj, cParams);
//3.反射调用固定长度参数的方法
Method unChangeMethod1 = sClazz.getDeclaredMethod("getParamsLength", String.class,String.class);
unChangeMethod1.invoke(sObj, "Hello","Java");
//也可以写成这样
Class[] clazzs = {String.class,String.class};
Method unChangeMethod2 = sClazz.getDeclaredMethod("getParamsLength", clazzs);
unChangeMethod2.invoke(sObj, "Hello","Java");
//下面的这种调用形式也是可以的,不过会报警告
// String[] params1 = {"Hello","Java"};
// unChangeMethod1.invoke(sObj, params1);
}
}