一、创建运行时类的对象
通过创建的运行时类的对象,进而创建类的对象。
@Test
public void test() throws IllegalAccessException, InstantiationException, NoSuchMethodException, InvocationTargetException {
Class clazz = Person.class;
/*
* newInstance()方法可以创建对应的运行时类的对象,内部调用了运行时类的空参构造器
* 运行时类必须提供空参的构造器
* 空参的构造器的访问权限允许。通常,设置为public。
* */
/*
*在javabean中要求提供一个public的空参构造器。原因:
1.便于通过反射,创建运行时类的对象
2.便于子类继承此运行时类时,默认调用super()时,保证父类此构造器
* */
Person p1 = (Person) clazz.newInstance();
System.out.println(p1);
}
如果在没有无参的构造器的情况下,实际上也可以创建类的对象,只要在操作的时候明确的调用类中的构造器,并将参数传递进去之后,就可以实例化类,创建类的对象。
@Test
public void test1() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException, InstantiationException {
//1.根据全类名获取对应的Class对象
Class clazz = Class.forName("ReflectionTest.Person");
//2.通过Class类的getDeclaredConstructor(Class … parameterTypes)取得本类的指定形参类型的构造器
// 向构造器的形参中传递一个对象数组进去,里面包含了构造器中所需的各个参数。
Constructor constructor = clazz.getDeclaredConstructor(String.class, int.class);
constructor.setAccessible(true);
//3.通过Constructor的实例创建对应类的对象,并初始化类属性
Person p1 = (Person)constructor.newInstance("zhangsan",25);
System.out.println(p1);
}
二、反射机制的“动态性”
运行时才确定需要创建的全类名,返回运行时类的对象。
@Test
public void test2(){
for(int i = 0;i < 100;i++){
int num = new Random().nextInt(3);//0,1,2
String classPath = "";
switch(num){
case 0:
classPath = "java.util.Date";
break;
case 1:
classPath = "java.lang.Object";
break;
case 2:
classPath = "ReflectionTest.Person";
break;
}
try {
Object obj = getInstance(classPath);
System.out.println(obj);
} catch (Exception e) {
e.printStackTrace();
}
}
}
/*
创建一个指定类的对象。
classPath:指定类的全类名
*/
public Object getInstance(String classPath) throws Exception {
Class clazz = Class.forName(classPath);
return clazz.newInstance();
}