Java 反射机制:(五)创建运行时类的对象

一、Class 可以做什么

  1、有了 Class 对象,能做什么?

    创建类的对象:调用 Class 对象的 newInstance() 方法

    要求:(1)类必须有一个无参数的构造器;

          (2)类的构造器的访问权限需要足够;

    执行 newInstance() 方法实际上是利用默认构造器(无参构造器)来创建该类的实例。

  2、难道没有无参的构造器就不能创建对象了吗?

    不是!只要在操作的时候明确的调用类中的构造器,并将参数传递进去之后,才可以实例化操作。

    步骤如下:

    (1)通过Class类的getDeclaredConstructor(Class … parameterTypes)取得本类的指定形参类型的构造器;
    (2)向构造器的形参中传递一个对象数组进去,里面包含了构造器中所需的各个参数。
    (3)通过Constructor实例化对象。

    

     创建运行时类的对象,是反射机制应用最多的地方。

二、创建运行时类的对象

  1、调用 newInstance() 方法

    案例:

 1     @Test
 2     public void test1() throws IllegalAccessException, InstantiationException {
 3 
 4         Class<Person> clazz = Person.class;
 5         /*
 6         newInstance():调用此方法,创建对应的运行时类的对象。内部调用了运行时类的空参的构造器。
 7 
 8         要想此方法正常的创建运行时类的对象,要求:
 9         1.运行时类必须提供空参的构造器
10         2.空参的构造器的访问权限得够。通常,设置为public。
11 
12 
13         在javabean中要求提供一个public的空参构造器。原因:
14         1.便于通过反射,创建运行时类的对象
15         2.便于子类继承此运行时类时,默认调用super()时,保证父类有此构造器
16 
17          */
18         Person obj = clazz.newInstance();
19         System.out.println(obj);
20 
21     }

  而且一般在编写 JavaBean 的时候,也建议提供无参的构造器。

  2、手动调用构造器

    案例:

 1     @Test
 2     public void test2() throws IllegalAccessException, InstantiationException {
 3     //1.获取对应的 Class 对象
 4     Class<Person> clazz = Person.class;
 5 
 6     //2. 调用指定参数结构的构造器,生成 Constructor 的实例
 7     Constructor con = clazz.getDeclaredConstructor(String.class,Integer.class);
 8 
 9     //3. 通过 Constructor 的实例创建对应类的对象,并初始化类属性
10     Person p2 = (Person) con.newInstance("Peter", 20);
11     System.out.println(p2);
12 
13     }

三、体会反射的动态性

  利用反射,我们可以在程序运行期间,动态的生成某个类的对象。

  案例:创建一个指定类的对象。

 1     /*
 2     创建一个指定类的对象。
 3     classPath:指定类的全类名
 4      */
 5     public Object getInstance(String classPath) throws Exception {
 6        Class clazz =  Class.forName(classPath);
 7        return clazz.newInstance();
 8     }
 9 
10     @Test
11     public void test2(){
12 
13         for(int i = 0;i < 100;i++){
14             int num = new Random().nextInt(3);//0,1,2
15             String classPath = "";
16             switch(num){
17                 case 0:
18                     classPath = "java.util.Date";
19                     break;
20                 case 1:
21                     classPath = "java.lang.Object";
22                     break;
23                 case 2:
24                     classPath = "com.java.Person";
25                     break;
26             }
27 
28             try {
29                 Object obj = getInstance(classPath);
30                 System.out.println(obj);
31             } catch (Exception e) {
32                 e.printStackTrace();
33             }
34         }
35     }

  在这里我们并不知道会创建那个类的对象,都是在程序运行期间随机创建的对象实例。

 

原文地址:https://www.cnblogs.com/niujifei/p/14882430.html