一、知识基础
java加载类进内存均是通过jvm的类加载器完成。java类在内存的唯一标志,其实是通过类加载器+类全名(包名+类名)。不同的类加载器加载同一个类是不会出现冲突的。
java的反射机制,是jdk提供的一套api,通过使用类加载器将指定的类动态加载进内存的方法。
二、目标
使用java反射机制创建一个实例对象,该类的构造方法的参数列表是可变长度的。
三、代码示例
try {
AInterface ai = Class.forName("com.sun.test.myapp.AClass", true,
Thread.currentThread().getContextClassLoader())
.asSubclass(AInterface.class)
.getDeclaredConstructor(String[].class).newInstance(new Object[] {
new String[] {"b", "c"}
});
System.out.println(ai.getClass().getSimpleName() + "::" + ai.getS0());
} catch (ClassNotFoundException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InstantiationException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalAccessException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (IllegalArgumentException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (InvocationTargetException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (NoSuchMethodException e) {
// TODO Auto-generated catch block
e.printStackTrace();
} catch (SecurityException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
上面代码中AClass的如下
public class AClass implements AInterface {
private String s0;
public AClass() {
s0 = "a";
}
public AClass(String... args) {
this.s0 = "::";
if(args.length >= 1) {
for(String s : args) {
this.s0 += s;
}
}
}
public AClass(String s0) {
this.s0 = s0;
}
public AClass(String s0, boolean f) {
if(f) {
this.s0 = s0;
}
}
public String getS0() {
return this.s0;
}
}
我们在getDeclaredConstructor中定义构造方法的参数类型使用的是数组类型,在newInstance进行实例创建时传递给构造方法的参数列表是一个数组,但该数组需要被Object数据包裹,直接传会报错。
四、结语
因为,在使用java反射时,创建可变长参数列表的构造方法的实例对象时,遇到一些问题,经过几番尝试才成功,故记录下来。