通过反射创建对象
当使用构造方法创建对象时,构造方法可以是有参数的,也可以是无参数的。同样,通过反射创建对象的方式也有两种,就是调用有参和无参构造方法,下面针对这两种方式进行详细讲解,具体如下:
1、通过无参构造实例化对象
如果想通过Class类本身实例化其他类的对象,那么就可以使用newInstance()方法,但是必须要保证被实例化的类中存在一个无参构造方法。接下来通过一个案例来演示如何通过无参构造实例化对象,如例1所示。
例1 ReflectDemo01.java
1 package cn.itcast.chapter08.reflection;
2 class Person {
3 private String name; //定义属性name,表示姓名
4 private int age; //定义属性age,表示年龄
5 public String getName() {
6 return name;
7 }
8 public void setName(String name) { //设置name属性
9 this.name = name;
10 }
11 public int getAge() {
12 return age;
13 }
14 public void setAge(int age) { //设置age属性
15 this.age = age;
16 }
17 public String toString() { //重写toString()方法
18 return "姓名:"+this.name+",年龄:"+this.age;
19 }
20 }
21 public class ReflectDemo01 {
22 public static void main(String[] args) throws Exception{
23 // 传入要实例化类的完整“包.类”名称
24 Class clazz = Class.forName("cn.itcast.chapter08.reflection.Person");
25 // 实例化Person对象
26 Person p = (Person) clazz.newInstance();
27 p.setName("李芳");
28 p.setAge(18);
29 System.out.println(p);
30 }
31 }
运行结果如图1所示。
图1 运行结果
在例1中,第24行代码通过Class.forName()方法实例化Class对象,向方法中传入的完整“包.类”名称的参数,第26行代码直接调用newInstance()方法实现对象的实例化操作。从图1中可以看出,程序输出了p对象的信息。
2、通过有参构造实例化对象
当通过有参构造方法实例化对象时,需要分为三个步骤完成,具体如下:
(1)通过Class类的getConstructors()方法取得本类中的全部构造方法。
(2)向构造方法中传递一个对象数组进去,里面包含了构造方法中所需的各个参数。
(3)通过Constructor类实例化对象。
需要注意的是,Constructor类表示的是构造方法,该类有很多常用的方法,具体如表1所示。
表1 Constructor类的常用方法
方法声明 | 功能描述 |
---|---|
int getModifiers() | 获取构造方法的修饰符。 |
String getName() | 获得构造方法的名称。 |
Class<?>[] getParameterTypes() | 获取构造方法中参数的类型。 |
T newInstance(Object... initargs) | 向构造方法中传递参数,实例化对象。 |
接下来,通过一个案例来演示如何通过有参构造实例化对象,如例2所示。
例2 InstanceDemo02.java
1 package cn.itcast.chapter08.reflection;
2 import java.lang.reflect.Constructor;
3 class Person {
4 private String name; //定义属性name,表示姓名
5 private int age; //定义属性age,表示年龄
6 public Person(String name, int age) {
7 this.name = name;
8 this.age = age;
9 }
10 public String getName() {
11 return name;
12 }
13 public void setName(String name) { //设置name属性
14 this.name = name;
15 }
16 public int getAge() {
17 return age;
18 }
19 public void setAge(int age) { //设置age属性
20 this.age = age;
21 }
22 public String toString() { //重写toString()方法
23 return "姓名:"+this.name+",年龄:"+this.age;
24 }
25 }
26 public class ReflectDemo02 {
27 public static void main(String[] args) throws Exception{
28 //传入要实例化类的完整“包.类”名称
29 Class clazz = Class.forName("cn.itcast.chapter08.reflection.Person");
30 //通过反射获取全部构造方法
31 Constructor cons[] = clazz.getConstructors();
32 //向构造方法中传递参数,并实例化Person对象
33 //因为只有一个构造方法,所以数组小标为0
34 Person p = (Person) cons[0].newInstance("李芳",30);
35 System.out.println(p);
36 }
37 }
运行结果如图2所示。
图2 运行结果
在例2中,第29行代码用于获取Person类的Class实例,第31行代码通过Class实例取得了Person类中的全部构造方法,并以对象数组的形式返回,第34行代码用于向构造方法中传递参数,并实例化Person对象,由于在Person类中只有一个构造方法,所以直接取出对象数组中的第一个元素即可。
需要注意的是,在实例化Person对象时,还必须考虑到构造方法中参数的类型顺序,第一个参数的类型为String,第二参数的类型为Integer。