通过反射创建运行时类的对象
我们一般创建对象的方式就是使用new关键字来完成,但其实我们通过反射的方式也可以创建对象
如何通过反射创建运行时类的对象
通过调用Class类中的newInstance()方法
- 调用此方法,会创建对应的运行时类的对象 , 内部是调用了运行时类的无参构造方法
- 此方法会抛出编译器异常:
- IllegalAccessException(非法访问异常)
- 如果运行时类的空参构造方法的访问权限被限制,这个时候调用不到这个运行时类的空参构造器的时候就会抛出此异常
- InstantiationException(实例化异常)
- 如果此运行时类没有空参构造方法,此时就会抛出此异常
- IllegalAccessException(非法访问异常)
- 由于此方法会抛出这两个异常,所以为了此方法可以正常的执行,也就是创建运行时类的对象,要求:
- 运行时类必须提供空参构造器
- 提供的空参构造器访问权限必须得够 — 通常设置为public
注意: 我们通过反射创建运行时类的对象除了使用Class类中的newInstance()非静态方法之外还可以通过Class实例调用getDeclaredConstructor()方法或者调用getConstructor()方法来获取到对应运行时类的某个构造器(可以是无参构造器,也可以是有参构造器),然后通过这个构造器来创建对应运行时类的对象
这里我们通过一个例字来理解如何通过反射来创建运行时类的对象
eg:
package 反射.通过反射创建对象;
public class Demo {
public static void main(String[] args) throws IllegalAccessException, InstantiationException {
//获取Person类对应的Class实例
Class<Person> clazz = Person.class;
/*
调用Class类中的newInstance()方法获取到Person类的对象
注意 : 这里默认调用了Person类中的无参构造器
*/
Person p = clazz.newInstance();
//打印输出, 我们在Person类中重写了toString()方法 ,这个时候输出的结果应该为: Person{name='null', id=0}
System.out.println(p);
}
}
我们通常要求一个类最好提供一个public的无参构造器,原因如下:
- 便于通过反射创建运行时类的对象
- 便于子类继承此运行时类,默认调用super()时,保证父类(也就是运行时类)有此构造器,也就保证了程序的正确性
补充:
Class类也是有泛型的,我们可以通过泛型来进行一个编译期间的控制
-
比如:
-
Class clazz1 = Person.class;
Object obj = clazz1.newInstance();
Person p = (Person)obj;
- 这个时候Class没有使用泛型,那么编译期间我们就会将Person类看作是Object类,所以我们获取到的就只能是Object类的实例
-
Class< person> clazz2 = Person.class;
Person p = clazz2.newInstance();
- 这个时候我们Class使用了泛型,这个时候编译期间进行了检查,所以这个时候我们就可以直接获取到Person类的实例
-