1. 程式人生 > 其它 >8.21Java反射訪問構造方法

8.21Java反射訪問構造方法

8.21Java反射訪問構造方法

構造Constructor型別的物件或者陣列動態獲取物件構造方法的資訊

構造一個Constructor物件或者陣列:

  • getConstructors()

  • getConstructor(Class<?>…parameterTypes)

  • getDeclaredConstructors()

  • getDeclaredConstructor(Class<?>...parameterTypes)

訪問指定的構造方法,需要根據該構造方法的入口引數的型別來訪問。

objectClass.getDeclaredConstructor(int.class,String.class); //入口引數型別依次為 int 和 String
objectClass.getDeclaredConstructor(new Class[]{int.class,String.class}); //入口引數型別依次為 int 和 String

建立的每個 Constructor 物件表示一個構造方法,然後利用 Constructor 物件的方法操作構造方法:

方法名稱說明
isVarArgs() 檢視該構造方法是否允許帶可變數量的引數,如果允許,返回 true,否則返回 false
getParameterTypes() 按照宣告順序以 Class 陣列的形式獲取該構造方法各個引數的型別
getExceptionTypes() 以 Class 陣列的形式獲取該構造方法可能丟擲的異常型別
newInstance(Object … initargs) 通過該構造方法利用指定引數建立一個該型別的物件,如果未設定引數則表示 採用預設無參的構造方法
setAccessiable(boolean flag) 如果該構造方法的許可權為 private,預設為不允許通過反射利用 netlnstance() 方法建立物件。如果先執行該方法,並將入口引數設定為 true,則允許建立對 象
getModifiers() 獲得可以解析出該構造方法所採用修飾符的整數

java.lang.reflect.Modifier類可以解析出getMocMers()方法的返回值所表示的修飾符資訊。

靜態方法名稱說明
isStatic(int mod) 如果使用 static 修飾符修飾則返回 true,否則返回 false
isPublic(int mod)
如果使用 public 修飾符修飾則返回 true,否則返回 false
isProtected(int mod) 如果使用 protected 修飾符修飾則返回 true,否則返回 false
isPrivate(int mod) 如果使用 private 修飾符修飾則返回 true,否則返回 false
isFinal(int mod) 如果使用 final 修飾符修飾則返回 true,否則返回 false
toString(int mod) 以字串形式返回所有修飾符

示例:

int modifiers = con.getModifiers();  // 獲取構造方法的修飾符整數
boolean isPublic = Modifier.isPublic(modifiers); // 判斷修飾符整數是否為public
string allModifiers = Modifier.toString(modifiers);

例項:

package PracticeReview.Reflect;

import java.lang.reflect.Constructor;

/**
* 使用java.lang包下的方法去獲取Practice類的資訊
* @since JDK 1.8
* @date 2021/08/23
* @author Lucifer
*/
public class ReflectTest {
public static void main(String[] args) {
//動態獲取ReflectPractice類
Class reflectPractice = PracticeReview.Reflect.ReflectPractice.class;

//獲取類下所以的構造方法
Constructor[] declaredContructors = reflectPractice.getDeclaredConstructors();

//遍歷所有構造方法
for (int i=0; i<declaredContructors.length; i++){
Constructor con = declaredContructors[i];
// 判斷構造方法的引數是否可變
System.out.println("檢視是否允許帶可變數量的引數:" + con.isVarArgs());
System.out.println("該構造方法的引數型別依次為:");

//獲取所有引數型別
Class[] parameterType = con.getParameterTypes();
for (int j=0; j<parameterType.length; j++){
System.out.println(" " + parameterType[j]);
}

System.out.println("可能丟擲的異常型別為:");
Class[] exceptionTypes = con.getExceptionTypes();
for (int j = 0; j < exceptionTypes.length; j++) {
System.out.println(" " + exceptionTypes[j]);
}

// 建立一個未例項化的Book類例項
ReflectPractice book1 = null;
while (book1 == null) {
try { // 如果該成員變數的訪問許可權為private,則丟擲異常
if (i == 1) {
// 通過執行帶兩個引數的構造方法例項化book1
book1 = (ReflectPractice) con.newInstance("Java 教程", 10);
} else if (i == 2) {
// 通過執行預設構造方法例項化book1
book1 = (ReflectPractice) con.newInstance();
} else {
// 通過執行可變數量引數的構造方法例項化book1
Object[] parameters = new Object[] { new String[] { "100", "200" } };
book1 = (ReflectPractice) con.newInstance(parameters);
}
} catch (Exception e) {
System.out.println("在建立物件時丟擲異常,下面執行 setAccessible() 方法");
con.setAccessible(true); // 設定允許訪問 private 成員
}
}
book1.print();
System.out.println("=============================\n");
}
}
}
It's a lonely road!!!