Java通过反射访问构造方法
為了能夠動態(tài)獲取對象構(gòu)造方法的信息,首先需要通過下列方法之一創(chuàng)建一個 Constructor 類型的對象或者數(shù)組。
getConstructors()getConstructor(Class<?>…parameterTypes)getDeclaredConstructors()getDeclaredConstructor(Class<?>...parameterTypes)如果是訪問指定的構(gòu)造方法,需要根據(jù)該構(gòu)造方法的入口參數(shù)的類型來訪問。例如,訪問一個入口參數(shù)類型依次為 int 和 String 類型的構(gòu)造方法,下面的兩種方式均可以實現(xiàn)。
objectClass.getDeclaredConstructor(int.class,String.class);objectClass.getDeclaredConstructor(new Class[]{int.class,String.class});創(chuàng)建的每個 Constructor 對象表示一個構(gòu)造方法,然后利用 Constructor 對象的方法操作構(gòu)造方法。
Constructor類的常用方法
| isVarArgs() | 查看該構(gòu)造方法是否允許帶可變數(shù)量的參數(shù),如果允許,返回 true,否則返回false |
| getParameterTypes() | 按照聲明順序以 Class 數(shù)組的形式獲取該構(gòu)造方法各個參數(shù)的類型 |
| getExceptionTypes() | 以 Class 數(shù)組的形式獲取該構(gòu)造方法可能拋出的異常類型 |
| newInstance(Object … initargs) | 通過該構(gòu)造方法利用指定參數(shù)創(chuàng)建一個該類型的對象,如果未設置參數(shù)則表示采用默認無參的構(gòu)造方法 |
| setAccessiable(boolean flag) | 如果該構(gòu)造方法的權(quán)限為 private,默認為不允許通過反射利用 netlnstance()方法創(chuàng)建對象。如果先執(zhí)行該方法,并將入口參數(shù)設置為 true,則允許創(chuàng)建對象 |
| getModifiers() | 獲得可以解析出該構(gòu)造方法所采用修飾符的整數(shù) |
通過 java.lang.reflect.Modifier 類可以解析出 getMocMers() 方法的返回值所表示的修飾符信息。在該類中提供了一系列用來解析的靜態(tài)方法,既可以查看是否被指定的修飾符修飾,還可以字符串的形式獲得所有修飾符。
Modifier類的常用方法
| 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) | 以字符串形式返回所有修飾符 |
下列代碼判斷對象 con 所代表的構(gòu)造方法是否被 public 修飾,以及以字符串形式獲取該構(gòu)造方法的所有修飾符。
int modifiers = con.getModifiers(); // 獲取構(gòu)造方法的修飾符整數(shù) boolean isPublic = Modifier.isPublic(modifiers); // 判斷修飾符整數(shù)是否為public string allModifiers = Modifier.toString(modifiers);示例如何調(diào)用 Constructor 類的方法獲取構(gòu)造方法的信息。
1 . 首先創(chuàng)建一個 Book 類表示圖書信息。在該類中聲明一個 String 型變量表示圖書名稱,兩個 int 型變量分別表示圖書編號和價格,并提供 3 個構(gòu)造方法。
Book 類的最終代碼如下:
public class Book {String name; // 圖書名稱int id, price; // 圖書編號和價格// 空的構(gòu)造方法private Book() {}// 帶兩個參數(shù)的構(gòu)造方法protected Book(String _name, int _id) {this.name = _name;this.id = _id;}// 帶可變參數(shù)的構(gòu)造方法public Book(String... strings) throws NumberFormatException {if (0 < strings.length)id = Integer.valueOf(strings[0]);if (1 < strings.length)price = Integer.valueOf(strings[1]);}// 輸出圖書信息public void print() {System.out.println("name=" + name);System.out.println("id=" + id);System.out.println("price=" + price);} }2 . 編寫測試類 Test,在該類的 main() 方法中通過反射訪問 Book 類中的所有構(gòu)造方法,并將該構(gòu)造方法是否帶可變類型參數(shù)、入口參數(shù)類型和可能拋出的異常類型信息輸出到控制臺。
Test 類的代碼如下:
public class Test {public static void main(String[] args) {// 獲取動態(tài)類BookClass book = Book.class;// 獲取Book類的所有構(gòu)造方法Constructor[] declaredContructors = book.getDeclaredConstructors();// 遍歷所有構(gòu)造方法for (int i = 0; i < declaredContructors.length; i++) {Constructor con = declaredContructors[i];// 判斷構(gòu)造方法的參數(shù)是否可變System.out.println("查看是否允許帶可變數(shù)量的參數(shù):" + con.isVarArgs());System.out.println("該構(gòu)造方法的入口參數(shù)類型依次為:");// 獲取所有參數(shù)類型Class[] parameterTypes = con.getParameterTypes();for (int j = 0; j < parameterTypes.length; j++) {System.out.println(" " + parameterTypes[j]);}System.out.println("該構(gòu)造方法可能拋出的異常類型為:");// 獲取所有可能拋出的異常類型Class[] exceptionTypes = con.getExceptionTypes();for (int j = 0; j < exceptionTypes.length; j++) {System.out.println(" " + parameterTypes[j]);}// 創(chuàng)建一個未實例化的Book類實例Book book1 = null;while (book1 == null) {try { // 如果該成員變量的訪問權(quán)限為private,則拋出異常if (i == 1) {// 通過執(zhí)行帶兩個參數(shù)的構(gòu)造方法實例化book1book1 = (Book) con.newInstance("Java 教程", 10);} else if (i == 2) {// 通過執(zhí)行默認構(gòu)造方法實例化book1book1 = (Book) con.newInstance();} else {// 通過執(zhí)行可變數(shù)量參數(shù)的構(gòu)造方法實例化book1Object[] parameters = new Object[] { new String[] { "100", "200" } };book1 = (Book) con.newInstance(parameters);}} catch (Exception e) {System.out.println("在創(chuàng)建對象時拋出異常,下面執(zhí)行 setAccessible() 方法");con.setAccessible(true); // 設置允許訪問 private 成員}}book1.print();System.out.println("=============================\n");}} }3 . 運行測試類 Test,當通過反射訪問默認構(gòu)造方法 Book() 時,將看到如下所示的輸出。
查看是否允許帶可變數(shù)量的參數(shù):false 該構(gòu)造方法的入口參數(shù)類型依次為: 該構(gòu)造方法可能拋出的異常類型為: 在創(chuàng)建對象時拋出異常,下面執(zhí)行setAccessible()方法 name = null id = 0 price = 0 =============================當通過反射訪問兩個參數(shù)的構(gòu)造方法 Book(String_name,int_id) 時,將看到如下所示的輸出。
查看是否允許帶可變數(shù)量的參數(shù):false 該構(gòu)造方法的入口參數(shù)類型依次為: class java.lang.String int 該構(gòu)造方法可能拋出的異常類型為: 在創(chuàng)建對象時拋出異常,下面執(zhí)行setAccessible()方法 name = null id = 0 price = 0 =============================當通過反射訪問可變參數(shù)數(shù)量的構(gòu)造方法 Book(String…strings) 時,將看到如下所示的輸出。
查看是否允許帶可變數(shù)量的參數(shù):true 該構(gòu)造方法的入口參數(shù)類型依次為: class java.lang.String; 該構(gòu)造方法可能拋出的異常類型為: class java.lang.String; 在創(chuàng)建對象時拋出異常,下面執(zhí)行setAccessible()方法 name = null id = 0 price = 0 =============================總結(jié)
以上是生活随笔為你收集整理的Java通过反射访问构造方法的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Java集合转化为数组
- 下一篇: Java 将文件的内容复制到另一个文件