Java反射
1-1访问构造方法
思路如下:
- 创建Class类对象,以获得constructor[ ]
循环或流访问每一个构造方法:获得修饰符、异常信息类型、入口参数类型 - 如果是if i==2,此时构造方法修饰符是private,需要用setAccessible方法绕过系统权限,根据constructor1.newinstance()创建对象。
Class exampleC=Example01.class;//先获得Example01对应的Class类
//获得所有构造方法
Constructor[] constructor=exampleC.getDeclaredConstructors();
for(int i=0;i<constructor.length;i++) {
Constructor constructor1 = constructor[i];
System.out.println("查看是否允许带有可变参数类型的变量:" + constructor1.isVarArgs());
System.out.println("该构造方法的入口参数类型依次为");
Class[] parameterTypes = constructor1.getParameterTypes();//获取入口参数类型
for (Class c : parameterTypes) {
System.out.println("" + c);
}
//获得所有可能抛出的异常信息类型
System.out.println("获得所有可能抛出的异常类型");
Class[] exception = constructor1.getExceptionTypes();
for (Class c : exception) {
System.out.println("" + c);
}
Example01 example01 = null;
while (example01 == null) {
try {
if (i == 2) {//通过执行没有参数的构造方法创建对象
example01 = (Example01) constructor1.newInstance();
} else if (i == 1) {
example01 = (Example01) constructor1.newInstance("7", 5);
} else {
//可变参数
String[][] parameters = {{"100", "200", "300"}};
example01 = (Example01) constructor1.newInstance(parameters);
}
}catch(Exception e){
System.out.println("在创建对象时抛出异常,下面执行setAcessable");
constructor1.setAccessible(true);
e.printStackTrace();
}
}
}
其中Example01类代码如下:
public class Example01 {
String s;
int i,i2,i3;
public Example01(){
}
private Example01(String s,int i){
this.s=s;
this.i=i;
}
public Example01(String... strings) {//当添加参数的时候,一定要将其添加成String[][],因为JVM本身此时不会将其package.
if(strings.length>0){
i=Integer.valueOf(strings[0]);
}
else if(strings.length>1){
i2=Integer.valueOf(strings[1]);
}
else if(strings.length>2){
i3=Integer.valueOf(strings[2]);
}
}
public void print(){
System.out.println("s="+s);
System.out.println("i="+i);
System.out.println("i2="+i2);
System.out.println("i3="+i3);
}
}
其中需要注意的问题是:
- String… strings代表数量可变参数,在调用该构造方法时,需将其包装成String[][],否则会报wrong number of arguments的错误。
- 具体解释如下