java的內部類和靜態內部類(嵌套類)

背景

開發新項目,寫Swager的mode的時候用到了嵌套Model,因而在代碼中,出現了靜態內部類。在codeReview的時候稍微和你們聊了一下。尤爲是Static 修飾類和修飾對象和變量不同呢?java

定義

1. 內部類

  • 能夠將一個類的定義放在另外一個類的定義內部,這就是內部類;
  • 嵌套類是其封閉類的成員。非靜態嵌套類(內部類)能夠訪問封閉類的其餘成員,即便它們被聲明爲私有的也是如此。靜態嵌套類無權訪問封閉類的其餘成員。爲一體的一個部件OuterClass,一個嵌套類能夠聲明private,public,protected,或包專用。(回想一下,只能聲明外部類public或將其包裝爲私有。)

2. 靜態內部類

  • 再一個普通類裏面,給內部類加上static關鍵字的修飾;
  • 與類方法和變量同樣,靜態嵌套類與其外部類相關聯。與靜態類方法同樣,靜態嵌套類不能直接引用其封閉類中定義的實例變量或方法:它只能經過對象引用來使用它們。(就和兩個普通不一樣的類之間的使用)

3. 二者的區別

  • 內部類只是外部類的成員變量,通俗講,就是你只能經過先調用外部類才能去拿到這個類(可是這是和組合仍是有區別的)。
  • 可是靜態內部類就像是一個普通類同樣。能夠直接調用,直接去new對象。

4. Java 擁有嵌套類有什麼做用呢?

  • 這是一種對僅在一個地方使用的類進行邏輯分組的方法:若是一個類僅對另外一個類有用,那麼將其嵌入該類並將二者保持在一塊兒是合乎邏輯的。嵌套此類「幫助程序類」可以使它們的程序包更加簡化。
  • 它增長了封裝:考慮兩個頂級類A和B,其中B須要訪問A的成員,不然將對其進行聲明private。經過將類B隱藏在類A中,能夠將A的成員聲明爲私有,而B能夠訪問它們。另外,B自己能夠對外界隱藏。
  • 這可能會致使代碼更具可讀性和可維護性:在頂級類中嵌套小類會使代碼更靠近使用位置。

Demo

  • talk is cheap ,Show me Code;
package 靜態內部類;

import com.sun.tools.internal.xjc.reader.xmlschema.bindinfo.BIConversion;
import javassist.runtime.Inner;
import lombok.Data;

/**
 * @authoryuanxindong
 * @date: 2020/6/19 10:25 下午
 */
@Data
public class OuterClassDemo {
    String outerStr;

    public OuterClassDemo(String outerStr) {
        this.outerStr = outerStr;
    }

    @Data
    public static class StaticInnerClass{
        public StaticInnerClass(String innerStr) {
            this.innerStr = innerStr;
        }

        private  String  innerStr;

    }
    @Data
    public class InnerClass{
        private String innerClassStr;
        public InnerClass(String outerStr) {
            //能夠和外部類通信
            this.innerClassStr = getOuterStr();
        }
    }

    public static void main(String[] args) {
        OuterClassDemo staticClassDemo =new OuterClassDemo("Outer");
        staticClassDemo.getOuterStr();
        // 內部正常類是不能直接new出來的
        //  OuterClass outerClass = new OuterClass();
        StaticInnerClass innerClass = new StaticInnerClass("StaticInner");
        System.out.println(innerClass.getInnerStr());
        initInnerClass();
    }
    public static void initInnerClass(){
        OuterClassDemo staticClassDemo1 = new OuterClassDemo("OuterClassDemo");
        InnerClass innerClass = staticClassDemo1.new InnerClass("outerStr");
        System.out.println(innerClass.getInnerClassStr());
    }
}

注意事項

  • 序列化強烈建議不要對內部類(包括 本地和 匿名類)進行序列化。當Java編譯器編譯某些構造(例如內部類)時,它會建立綜合構造。
  • 這些是類,方法,字段以及其餘在源代碼中沒有相應構造的構造。合成構造使Java編譯器無需更改JVM就能夠實現新的Java語言功能。可是,合成構造在不一樣的Java編譯器實現中可能有所不一樣,這意味着.class文件在不一樣的實現中也可能有所不一樣。所以,若是序列化一個內部類,而後使用其餘JRE實現對其進行反序列化,則可能會遇到兼容性問題。

核心討論

  • 瞭解了靜態內部類後,那static爲何修飾了類,對於這個類也是起了一個全局可用的一個做用?
  • 越想問題越多,還有就是爲何被Static 修飾的方法能夠被類直接引用到?而static 修飾的類也能夠被其餘的類直接使用,而不依賴於對象。

答 :咱們得明確一下json

  • static修飾類的方法,表示這個方法和這個類對象沒有關係,只是和這個類有關係
  • static 修飾變量,按照是否靜態的對類成員變量進行分類可分兩種:一種是被static修飾的變量,叫靜態變量或類變量;另外一種是沒有被static修飾的變量,叫實例變量。二者的區別是:
  • 對於靜態變量在內存中只有一個拷貝(節省內存),JVM只爲靜態分配一次內存,在加載類的過程當中完成靜態變量的內存分配,可用類名直接訪問(方便),固然也能夠經過對象來訪問(可是這是不推薦的)。
  • 好的,是這樣的。static修飾對象 能夠全局使用,修飾方法能夠不依賴於對象,修飾類,也不用依賴與他的對象,也能夠被其餘的類直接使用,或者本身進行初始化。

總結

  • 嵌套類:內部類和靜態內部類
  • 內部類屬於外部類的成員,必須依賴與外部對象來實現,靜態內部類,不依賴,能夠本身單獨實現。
  • static 的修飾 變量,類,方法,代碼塊。 共性全局性。變量的話也就是全劇惟一性,會出現多個飲用,但不會出現多個存儲。  
相關文章
相關標籤/搜索