【Java基礎】靜態內部類與普通內部類的區別

今天接到一個需求,是將公司的一些統計數據文件內容解析出來後,通過mq發給用戶運營平臺,給公司的大佬看,這個還是很簡單,半個小時就碼完了,但自測完後突然發現怎麼建了這麼多DTO(data transform object)!因爲統計文件有很多不同類型,我針對每個類型都建了相應的DTO,因爲這個DTO在其他業務也用不上,而且以後文件類型還有增加的話,那DTO也會增加,僅僅因爲這單個小功能產生這麼多利用率不高的DTO着實不太好(論項目是如何變臃腫的),所以我想到了一個辦法,建一個外部類,然後將這些文件對應的DTO作爲內部類放在裏面。但是內部類是用普通類還是靜態類呢?其實我也不知道,所以我好好研究了一番他們的區別。

我先貼下網上找到的關於普通內部類和靜態內部類的區別:

  1. 普通內部類持有對外部類的引用,靜態內部類沒有持有外部類的引用。

  2. 普通內部類能夠訪問外部類的靜態和非靜態成員,靜態內部類不能訪問外部類的非靜態成員,他只能訪問外部類的靜態成員。

  3. 一個普通內部類不能脫離外部類實體被創建,且可以訪問外部類的數據和方法,因爲他就在外部類裏面。


是不是一臉懵逼,哪裏引用了外部類?我怎麼沒看見?其實我看完後也是一臉懵逼,後來我猜想,這些是不是jdk將java文件編譯成class文件的過程中幫我們做了點手腳?爲了驗證猜想,於是乎做了下面實驗。

我先寫了一個很簡單的普通內部類和靜態內部類的代碼:

package com.yy.demo15_innerClass;

/**
 * @Author: 24只羊
 * @Date: 2020-02-24
 */
public class OuterClass {

    // 普通成員變量
    private String outField = "out field";
    // 靜態成員變量
    private static String outStaticField = "out static field";

    // 普通內部類
    public class InnerClassA{
    }
    // 靜態內部類
    public static class InnerStaticClassB{
    }
}

我們在idea或eclipse編譯這個類所在的項目後,這個OuterClass.java會生成三個Class文件:

OuterClass.class

OuterClass$InnerClassA.class

OuterClass$InnerStaticClassB.class

這個三個文件夾內容是啥呢?我們可以通過反編譯看看(我用的是在線反編譯,鏈接貼文末了)

反編譯後生成了:

OuterClass.java

OuterClass$InnerClassA.java

OuterClass$InnerStaticClassB.java

package com.yy.demo15_innerClass;

public class OuterClass {
   private String outField = "out field";
   private static String outStaticField = "out static field";
}
package com.yy.demo15_innerClass;

import com.yy.demo15_innerClass.OuterClass;

public class OuterClass$InnerClassA {

   // $FF: synthetic field
   final OuterClass this$0;

   public OuterClass$InnerClassA(OuterClass this$0) {
      this.this$0 = this$0;
   }
}
package com.yy.demo15_innerClass;

public class OuterClass$InnerStaticClassB {

}

我們可以看到普通內部類InnerClassA在編譯成class文件後,其自動在class文件中引用了外部類OuterClass,而內部靜態類則沒有引用外部類。

這樣普通內部類相比外部內部類有個好處——就是可以引用外部類的屬性以及方法。但凡事有兩面,因爲內部類裏面持有外部類的引用,如果內部類一直在執行,則外部類就不會被GC回收,如果外部類中含有大量資源,有可能會導致內存泄漏(安卓中比較常見,比如外部類中有大量圖片啥的,但是java後端這種情況的場景我還沒想到,可能太菜了吧!!!),所以擔心內存泄漏,就用靜態內部類吧。嗯嗯,我的需求也是用的靜態內部類。

現在我們再看看本文開頭的總結,是不是一目瞭然!

最後貼下我用的在線反編譯鏈接地址:http://javare.cn/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章