8.21Java反射訪問構造方法
阿新 • • 發佈:2021-08-23
構造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();