<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          靈魂拷問:Java內(nèi)部類是如何訪問外部類私有對象的?

          共 2831字,需瀏覽 6分鐘

           ·

          2021-03-12 18:52

          點擊上方 好好學(xué)java ,選擇 星標 公眾號

          重磅資訊,干貨,第一時間送達

          今日推薦:14 個 github 項目!

          個人原創(chuàng)100W +訪問量博客:點擊前往,查看更多

          作者:Aaron濤
          blog.csdn.net/qq_33330687/article/details/77915345

          我們都是知道內(nèi)部類就是寫在一個類里面的類,類里面的類,不知道你們有沒有看過javac之后的結(jié)果,就是將一個外部類編譯后,生成的字節(jié)碼文件結(jié)果

          public class OutClass{
           
           private String name;
           private int id;
           private String address;
           
           
           
           public class innerClass{
            
            private String innerName;
            public void fun(){
             System.out.println(OutClass.this.name+": "+innerName);
             System.out.println(OutClass.this.id+": "+innerName);
             System.out.println(OutClass.this.address+": "+innerName);
            }
            public innerClass(String innerName){
             this.innerName = innerName;
            }
            
           }
          }

          這是我簡單手寫的一個外部類中嵌套一個內(nèi)部類。

          當我編譯這段代碼javac OutClass.java

          可以看出會生成兩個.class字節(jié)碼文件,內(nèi)部類的類名是外部類類名$內(nèi)部類類名

          然后對這個兩個字節(jié)碼文件反編譯看看javap

          可以看到,外部類OutClass除了默認構(gòu)造器和私有的屬性:name,id,address還多了三個靜態(tài)的方法,這三個方法不是我們手寫的。是編譯器自動生成的,什么作用呢。

          不曉得?乛?乛?,然后看內(nèi)部類OutClass$innerClass ,發(fā)現(xiàn)編譯器也做了修改,首先,多了一個常量引用,final OutClass this$0 很明顯,這就是指向外部類的引用,有了引用怎么對他賦值呢,然后我們看到了那個構(gòu)造方法,我自己的源代碼中構(gòu)造方法的參數(shù)只有一個String innerName 而通過反編譯我看到了多了一個參數(shù),一個類型為OutClass,這就很明顯了嘛。

          編譯器小哥偷偷的做了一些不可告人的事情,首先,內(nèi)部類中多了個常量引用,準備指向著外部類,而且又偷偷修改了構(gòu)造方法。傳遞一個OutClass類型的參數(shù)進去。這樣內(nèi)部類就拿到了外部類的引用。

          但是僅僅拿到引用有個毛線用,通過反編譯可以看到,生成的是兩個字節(jié)碼文件,在虛擬機看來,這就是兩個不相關(guān)的類,你能在一個類中調(diào)用另外一個類的私有屬性嗎???

          很明顯不能。這個時候我做了個方法的測試呀,我們都知道,內(nèi)部類使用外部類的屬性用過外部類類名.this.屬性名,所以我寫了個測試方法fun

          public void fun(){
             System.out.println(OutClass.this.name+": "+innerName);
             System.out.println(OutClass.this.id+": "+innerName);
             System.out.println(OutClass.this.address+": "+innerName);
            }

          然后我們通過反編譯看看這段代碼怎么執(zhí)行的。嘿嘿反編譯真是個好東西(●′?`●)4

          javap -c OutClass$innerClass

          看上去看不懂有點復(fù)雜,但是沒關(guān)系我們看右邊,看我紅色箭頭,是不是有點屬性,

          Field this$0:LOutClass;

          Method OutClass.access$000:(LOutClass;)Ljava/lang/String;

          截取一部分,看見沒有,上面那個屬性是內(nèi)部類自動生成的常量指針,下面那個方法是外部類自動生成的三個靜態(tài)方法。將指向外部類的引用作為參數(shù)給那三個外部類中的靜態(tài)方法

          然后我們?nèi)シ淳幾g看看那三個靜態(tài)方法怎么實現(xiàn)的

          又是祭出偉大的反編譯工具

          看得出,這三個方法都是返回外部類對應(yīng)的私有屬性!不過對于這點我還有點要說明,編譯器很智能,它會掃描內(nèi)部類,查看是否調(diào)用的外部類的私有屬性,只有調(diào)用了才會生成對應(yīng)的acess$xxx方法!

          結(jié)論

          在虛擬機中沒有外部類內(nèi)部類之分都是普通的類,但是編譯器會偷偷的做點修改,讓內(nèi)部類中多一個常量引用指向外部類,自動修改內(nèi)部類構(gòu)造器,初始化這個常量引用,而外部類通過掃描內(nèi)部類調(diào)用了外部類的那些私有屬性,為這些私有屬性創(chuàng)造acess$xxx靜態(tài)方法。這個方法是返回對應(yīng)的私有屬性的值。所以可以在一個類的外部獲取一個類的私有屬性的值

          推薦文章
          更多項目源碼

          瀏覽 42
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  久久成人理论电影手机 | 欧美变态拉屎操逼网站 | 日韩A片免费视频 | 精品无码一区二区三区四区 | 青青草撸视频 |