1. 程式人生 > >利用反射機制獲得非靜態內部類之getConstructor的用法探索

利用反射機制獲得非靜態內部類之getConstructor的用法探索

 來源: http://blog.163.com/[email protected]/blog/static/161553399201291311119821/

提問關於反射機制拿到內部類的構造方法的問題。總結一下個人學習新東西的過程。 

import java.lang.reflect.*; publicclassTest1{ publicstaticvoid main(String[] args)throwsException { Class cls =Test1.Person.class; System.out.println(cls);//這句話的列印說明已經拿到了內部類的位元組碼物件。 Constructor

con = cls.getConstructor(null); System.out.println(con.getName()); System.out.println(con.getModifiers()); } //內部類 classPerson{ privateString name; publicPerson(){} } }

Constructor con = cls.getConstructor(null);這一行丟擲java.lang.NoSuchMethodException 異常
替換為Constructor con = cls.getConstructors()[0];之後,報錯解決了,可究竟為什麼用getConstructor就不行呢?
首先查API,搜尋getConstructor得到的結果是 

getConstructor

返回一個Constructor物件,它反映此Class物件所表示的類的指定公共構造方法。parameterTypes引數是Class物件的一個數組,這些Class物件按宣告順序標識構造方法的形參型別。如果此Class物件表示非靜態上下文中宣告的內部類,則形參型別作為第一個引數包括顯示封閉的例項。

要反映的構造方法是此Class物件所表示的類的公共構造方法,其形參型別與parameterTypes所指定的引數型別相匹配。

引數:
parameterTypes-引數陣列
返回:
與指定的parameterTypes相匹配的公共構造方法的
Constructor物件
丟擲:
意味著若是要使用getConstructors方法得到正確結果,必須傳入一個引數parameterTypes。這個引數型別為Class。二話不說,指定為
Constructor con = cls.getConstructor(Test1.Person.class);結果依舊報錯。這是何故?
只好繼續看API提示,先來個輸出語句,看看利用之前獲得的cls.getConstructors()[0]究竟是個什麼玩意兒?加上下面這條語句

Class[] parameterTypes = con.getParameterTypes(); for(int i =0; i < parameterTypes.length; i++){ System.out.println(parameterTypes[i]); }

輸出結果為:class Test1
既然有了parameterTypes,換回原來的Constructor con = cls.getConstructor(Test1.class);完整程式碼如下

import java.lang.reflect.*;

publicclassTest1{ publicstaticvoid main(String[] args)throwsException{ Class cls =Test1.Person.class; //System.out.println(cls);//這句話的列印說明已經拿到了內部類的位元組碼物件。 Constructor con = cls.getConstructor(Test1.class);//傳入外包裝類作為引數 System.out.println(con.getName()); System.out.println(con.getModifiers()); }

// 內部類 classPerson{ privateString name; publicPerson(){}

} }

這時我們回到API文件中,注意到這麼一句話:如果此 Class 物件表示非靜態上下文中宣告的內部類,則形參型別作為第一個引數包括顯示封閉的例項。 恰巧有位同學把官方英文版API也貼出來了 include the explicit enclosing instance as the first parameter
看到這裡,我們可以得到解釋,為什麼傳入的引數不是Test1.Person.class而是Test1.class
果然原版的API表達的意思會更飽滿更易懂。這裡翻譯過來,應該是這個意思:非靜態上下文中宣告的內部類,應該把外部包裝類當做第一個引數,故此應該傳入Test1.class

isAssignableFrom  是否父子類

Java Package.isAnnotationPresent()方法用法例項教程。方法返回true,如果

指定型別的註釋存在於此元素上, 否則返回false。這種方法的設計主要是為了方

便訪問標記註釋