15_Java反射機制——3.建立執行時類的物件
阿新 • • 發佈:2022-03-21
目錄
問題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(); } }