關(guān)于Java反射機制中通過getConstructors()方法獲取類中全部構(gòu)造方法順序的問題

關(guān)于Java反射機制中通過getConstructors方法獲取類中全部構(gòu)造方法順序的問題

近日學(xué)習(xí)java反射機制的過程中了解到的getConstructors()方法,此方法用于取得全部構(gòu)造方法,在測試過程發(fā)現(xiàn)了一些問題往衷,希望與大家分享。

問題引入

以下代碼用于取得Person類中的全部構(gòu)造方法:

package reflectDemo01;
import java.lang.reflect.Constructor;       //導(dǎo)入反射包
class Person{
    private String name;
    private int age;
    public Person(String name) {            //第一個構(gòu)造方法
        this.setName(name);
    }
    public Person(String name,int age) {    //第二個構(gòu)造方法
        this.setName(name);
        this.setAge(age);
    }
    public void setName(String name) {
        this.name=name;
    }
    public void setAge(int age) {
        this.age=age;
    }
    public String toString() {              //覆寫toString()方法
        return "姓名:"+this.name+"  年齡:"+this.age;
    }
}
public class ReflectDemo01 {
    public static void main(String args[]) {
        Class<?>c=null;                                 //聲明Class對象
        try {
            c=Class.forName("reflectDemo01.Person");    //實例化Class對象
        } catch (ClassNotFoundException e) {
            e.printStackTrace();                        //處理異常
        }           
        Constructor<?> cons[]=c.getConstructors();      //取得全部公共構(gòu)造方法
        for(int i=0;i<cons.length;i++) {
            System.out.println(cons[i]);                //循環(huán)輸出
        }
    }
}

運行結(jié)果如下:



通過運行結(jié)果可以看到返回的對象數(shù)組中構(gòu)造方法的順序是定義的順序
這時將定義的兩個構(gòu)造方法位置交換:

public Person(String name,int age) {    //原第二個構(gòu)造方法
        this.setName(name);
        this.setAge(age);
    }
    public Person(String name) {        //原第一個構(gòu)造方法
        this.setName(name);
    }

得到如下結(jié)果:


兩個構(gòu)造方法交換后的結(jié)果

輸出結(jié)果也交換了順序黑忱,與定義的順序一致。那我們是否能得出通過getConstructors()方法獲取的構(gòu)造方法順序與定義順序一致的結(jié)論呢勒魔?

此時將一個無參構(gòu)造方法加入代碼甫煞,:

public Person(){}                       //新加入的無參構(gòu)造
    public Person(String name,int age) {    //原第二個構(gòu)造方法
        this.setName(name);
        this.setAge(age);
    }
    public Person(String name) {            //原第一個構(gòu)造方法
        this.setName(name);
    }

運行結(jié)果如下:


加入無參構(gòu)造后的運行結(jié)果

運行結(jié)果可見輸出順序是逆序,并不是定義的順序冠绢,再調(diào)換一下順序:

    public Person(String name) {            //第一個構(gòu)造方法
        this.setName(name);
    }
    public Person(String name,int age) {    //第二個構(gòu)造方法
        this.setName(name);
        this.setAge(age);
    }
    public Person(){}                       //新加入的無參構(gòu)造

再次調(diào)換順序后的運行結(jié)果:


三個構(gòu)造方法交換順序的運行結(jié)果

輸出的結(jié)果仍是逆序危虱,那到底getConstructors()方法返回結(jié)果的順序如何?

問題引入

public Constructor<?>[] getConstructors() throws SecurityException

查看API文檔后發(fā)現(xiàn)getConstructors()方法返回的是此類公共構(gòu)造方法的 Constructor 對象數(shù)組 ,并沒有對數(shù)組存儲順序的描述唐全,于是我猜測此方法用了棧(Stack)的存儲方式埃跷,最后用先進后出(FILO)的方式輸出蕊玷。

為了驗證猜測,我向Person類中添加了一個浮點型(Float)的屬性score,并增加了一個構(gòu)造方法弥雹。

    private String name;
    private int age;    
    private float score;
    public Person(){}                           //第一個無參構(gòu)造
    public Person(String name) {                //第二個構(gòu)造方法
        this.setName(name);
    }
    public Person(String name,int age) {        //第三個構(gòu)造方法
        this.setName(name);
        this.setAge(age);
    }   
    public Person(float score) {}               //新增的第四個構(gòu)造方法

運行結(jié)果:


增加之后

此時無論怎么調(diào)換方法順序垃帅,仍是逆序輸出,但再次加入2個構(gòu)造方法之后剪勿,順序發(fā)生了變化

public Person(){}                                       //  第一個無參構(gòu)造
    public Person(String name) {                        //第二個構(gòu)造方法
        this.setName(name);
    }
    public Person(String name,int age) {                //第三個構(gòu)造方法
        this.setName(name);
        this.setAge(age);
    }   
    public Person(float score) {}                       //第四個構(gòu)造方法       
    public Person(String name,float score) {}           //新增的第五個構(gòu)造方法
    public Person(String name,int age,float score) {}   //新增的第六個構(gòu)造方法

運行結(jié)果:


從運行結(jié)果可以看見輸出順序發(fā)生了變化贸诚,雖然有一定規(guī)律但并不是有序的,由此便可以得出結(jié)論厕吉。

問題結(jié)論

進一步查看API文檔發(fā)現(xiàn)在getDeclaredConstructors()方法的描述中有這樣一句話:

The elements in the array returned are not sorted and are not in any particular order.

也就是說返回數(shù)組中的元素沒有排序酱固,也沒有任何特定的順序,這樣的描述同時存在于getDeclaredFields()方法和getDeclaredMethods()中头朱。我又向Person類中加入了若干構(gòu)造方法运悲,發(fā)現(xiàn)分別在第3,6,13,15,27次時,輸出順序全部發(fā)生改變项钮。由此可以得出結(jié)論:

① 在取得全部構(gòu)造方法班眯,普通方法和屬性的時候,返回數(shù)組里元素的位置是完全隨機的烁巫。

② 這種隨機指的不是每次執(zhí)行返回的結(jié)果不同署隘,而是隨著方法和屬性的增加而改變返回順序。

所以不要采用getConstructors()方法亚隙,用數(shù)組下標獲取構(gòu)造方法的方式初始化對象磁餐,以免以后在類中新增構(gòu)造方法時出現(xiàn)異常。
可以采用較為安全的getConstrutor()方法指定參數(shù)類型阿弃,再通過newInstance()方法為對象初始化:

Constructor<?> con1=c.getConstructor(String.class,int.class);       //指定參數(shù)類型
        Person per=(Person)con1.newInstance("MaYuKang",20);         //傳入?yún)?shù)
        System.out.println(per);

運行結(jié)果:


以上所有代碼及運行結(jié)果均使用Eclipse編譯器崖媚,JDK10.0.1版本。如有描述不當恤浪,望大家多多糾正與補充,覺得有用就點個贊唄肴楷。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末水由,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子赛蔫,更是在濱河造成了極大的恐慌砂客,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件呵恢,死亡現(xiàn)場離奇詭異鞠值,居然都是意外死亡,警方通過查閱死者的電腦和手機渗钉,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門彤恶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來钞钙,“玉大人,你說我怎么就攤上這事声离∶⒘叮” “怎么了?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵术徊,是天一觀的道長本刽。 經(jīng)常有香客問我,道長赠涮,這世上最難降的妖魔是什么子寓? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任,我火速辦了婚禮笋除,結(jié)果婚禮上斜友,老公的妹妹穿的比我還像新娘。我一直安慰自己株憾,他們只是感情好蝙寨,可當我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著嗤瞎,像睡著了一般墙歪。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上贝奇,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天虹菲,我揣著相機與錄音,去河邊找鬼掉瞳。 笑死毕源,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的陕习。 我是一名探鬼主播霎褐,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼该镣!你這毒婦竟也來了冻璃?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤损合,失蹤者是張志新(化名)和其女友劉穎省艳,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體嫁审,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡跋炕,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了律适。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片辐烂。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡杆煞,死狀恐怖喷鸽,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤油够,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布质帅,位于F島的核電站鹿驼,受9級特大地震影響紊婉,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜德召,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一白魂、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧上岗,春花似錦福荸、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至呆瞻,卻和暖如春台夺,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背痴脾。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工颤介, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人赞赖。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓滚朵,卻偏偏與公主長得像,于是被迫代替她去往敵國和親前域。 傳聞我的和親對象是個殘疾皇子辕近,可洞房花燭夜當晚...
    茶點故事閱讀 42,786評論 2 345