学科分类
目录
Java Web

通过反射创建对象

当使用构造方法创建对象时,构造方法可以是有参数的,也可以是无参数的。同样,通过反射创建对象的方式也有两种,就是调用有参和无参构造方法,下面针对这两种方式进行详细讲解,具体如下:

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所示。

img

图2 运行结果

在例2中,第29行代码用于获取Person类的Class实例,第31行代码通过Class实例取得了Person类中的全部构造方法,并以对象数组的形式返回,第34行代码用于向构造方法中传递参数,并实例化Person对象,由于在Person类中只有一个构造方法,所以直接取出对象数组中的第一个元素即可。

需要注意的是,在实例化Person对象时,还必须考虑到构造方法中参数的类型顺序,第一个参数的类型为String,第二参数的类型为Integer。

点击此处
隐藏目录