1. 程式人生 > 其它 >15_Java反射機制——3.建立執行時類的物件

15_Java反射機制——3.建立執行時類的物件

目錄

問題1: Class 物件 (或 Class 例項) 能做什麼?

1. Class 物件 對應於一個 .class 檔案,即 執行時類。
2. 呼叫 Class 物件 的 newInstance() 方法,可以用來 建立 執行時類的物件。

要 求: 
    1)類必須有一個無引數的構造器。
    2)類的構造器的訪問許可權需要足夠。

問題2: 難道沒有無參的構造器就不能建立物件了嗎?

不是!只要在操作的時候,明確地呼叫類中的構造器, 並將引數傳遞進去之後,才可以例項化操作。

步驟如下:
    1)通過Class類的getDeclaredConstructor(Class … parameterTypes)取得本類的指定形參類
       型的構造器。
    2)向構造器的形參中傳遞一個物件陣列進去,裡面包含了構造器中所需的各個引數(引數個數可以為0)。
    3)通過Constructor例項化物件。

    eg:
    // 1. 根據 全類名 獲取  Class 例項 ——  執行時類(即 對應一個 .class 檔案)
    String  className = "com.atzwx.java.Employee";
    Class clazz = Class.forName(className);
    // 2. 通過 執行時類 獲取 類成員(構造器、方法、屬性)
    Constructor constructor = clazz.getConstructor();
    // 3. 通過Constructor例項化物件。
    Employee employee = (Employee) constructor.newInstance();               

舉 例 : 建立執行時類的物件

【Employee】

//package com.atzwx.java;

public class Employee {

    private Integer id = 1;

    private String name;

    private Integer age = 20;

    private String address;

    public int works = 90;

    public Employee() {
    }

    public Integer getId() {
        return id;
    }

    public void setId(Integer id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getAddress() {
        return address;
    }

    public void setAddress(String address) {
        this.address = address;
    }

    public int getWorks() {
        return works;
    }

    public void setWorks(int works) {
        this.works = works;
    }

    @Override
    public String toString() {
        return "Employee{" +
                "id=" + id +
                ", name='" + name + '\'' +
                ", age=" + age +
                ", address='" + address + '\'' +
                ", works=" + works +
                '}';
    }

    //@Override
    public void work() {
        System.out.println("Employee.work");
    }

    //@Override
    public void say() {
        System.out.println("Employee.say");
    }

    //@Override
    public void study() {
        System.out.println("Employee.study");
    }
}

【ReflectTest】

//package com.atzwx.test;

import com.atzwx.java.Employee;
import org.junit.Test;

import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;

public class ReflectTest {

    /**
     * 通過 Class 物件,呼叫 newInstance() 方法, 來 建立 執行時類的物件
     * @throws Exception
     */
    @Test
    public void reflectTest() throws Exception {

        // 說明: Class 是一個用來 描述類 的 類 ,通過 Class 類 可以獲取 一個 類的相關資訊
        // 1. 根據 全類名 獲取  Class 例項 ——  執行時類(即 對應一個 .class 檔案)
        String  className = "com.atzwx.java.Employee"; // Employee 類的全類名,按自己的實際全類名來填寫
        Class clazz = Class.forName(className);
        System.out.println("clazz: " + clazz); // cclazz: class com.atzwx.java.Employee
        System.out.println();

        // 2. 通過 Class 例項 ( 物件 ) 的 newInstance() 方法,來獲取 執行時類 的 例項 (物件)
        Object realObj = clazz.newInstance();
        System.out.println("realObj: " + realObj); // realObj: Employee{id=1, name='null', age=20, address='null', works=90}
        System.out.println();

        // 3. 通過 執行時類 獲取 類成員(構造器、方法、屬性)
        Constructor constructor = clazz.getConstructor();
        System.out.println("constructor: " + constructor); // constructor: public com.atzwx.java.Employee()
        Employee employee = (Employee) constructor.newInstance();
        System.out.println("employee: " + employee); // employee: Employee{id=1, name='null', age=20, address='null', works=90}
        System.out.println();

        Method method = clazz.getMethod("work");
        System.out.println("method: " + method); // method: public void com.atzwx.java.Employee.work()
        method.invoke(realObj); // Employee.work
        System.out.println();

        Method methodDeclared = clazz.getDeclaredMethod("say");
        System.out.println("methodDeclared: "+ methodDeclared); // methodDeclared: public void com.atzwx.java.Employee.say()
        methodDeclared.invoke(realObj); // Employee.say
        System.out.println();

        Field field = clazz.getField("works");
        System.out.println("field: " + field); // field: public int com.atzwx.java.Employee.works
        System.out.println();

    }

}