背景
開發(fā)新項目,寫Swager的mode的時候用到了嵌套Model,于是在代碼中,出現(xiàn)了靜態(tài)內(nèi)部類。在codeReview的時候稍微和大家聊了一下。尤其是Static 修飾類和修飾對象和變量不一樣呢?
定義
1. 內(nèi)部類
1.可以將一個類的定義放在另一個類的定義內(nèi)部,這就是內(nèi)部類;
2.嵌套類是其封閉類的成員。非靜態(tài)嵌套類(內(nèi)部類)可以訪問封閉類的其他成員,即使它們被聲明為私有的也是如此。靜態(tài)嵌套類無權訪問封閉類的其他成員。為一體的一個部件OuterClass,一個嵌套類可以聲明private,public,protected,或包專用。(回想一下,只能聲明外部類public或?qū)⑵浒b為私有。)
2. 靜態(tài)內(nèi)部類
1.再一個普通類里面,給內(nèi)部類加上static關鍵字的修飾;
2.與類方法和變量一樣,靜態(tài)嵌套類與其外部類相關聯(lián)。與靜態(tài)類方法一樣,靜態(tài)嵌套類不能直接引用其封閉類中定義的實例變量或方法:它只能通過對象引用來使用它們。(就和兩個普通不同的類之間的使用)
3. 兩者的區(qū)別
1.內(nèi)部類只是外部類的成員變量,通俗講,就是你只能通過先調(diào)用外部類才能去拿到這個類(但是這是和組合還是有區(qū)別的)。
2.但是靜態(tài)內(nèi)部類就像是一個普通類一樣。可以直接調(diào)用,直接去new對象。
4. Java 擁有嵌套類有什么作用呢?
1.這是一種對僅在一個地方使用的類進行邏輯分組的方法:如果一個類僅對另一個類有用,那么將其嵌入該類并將兩者保持在一起是合乎邏輯的。嵌套此類“幫助程序類”可使它們的程序包更加簡化。
2.它增加了封裝:考慮兩個頂級類A和B,其中B需要訪問A的成員,否則將對其進行聲明private。通過將類B隱藏在類A中,可以將A的成員聲明為私有,而B可以訪問它們。另外,B本身可以對外界隱藏。
3.這可能會導致代碼更具可讀性和可維護性:在頂級類中嵌套小類會使代碼更靠近使用位置。
Demo
talk is cheap ,Show me Code;
package 靜態(tài)內(nèi)部類;
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();
// 內(nèi)部正常類是不能直接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());
}
}
注意事項
1.序列化強烈建議不要對內(nèi)部類(包括 本地和 匿名類)進行序列化。當Java編譯器編譯某些構造(例如內(nèi)部類)時,它會創(chuàng)建綜合構造。
2.這些是類,方法,字段以及其他在源代碼中沒有相應構造的構造。合成構造使Java編譯器無需更改JVM就可以實現(xiàn)新的Java語言功能。但是,合成構造在不同的Java編譯器實現(xiàn)中可能有所不同,這意味著.class文件在不同的實現(xiàn)中也可能有所不同。因此,如果序列化一個內(nèi)部類,然后使用其他JRE實現(xiàn)對其進行反序列化,則可能會遇到兼容性問題。
核心討論
1.了解了靜態(tài)內(nèi)部類后,那static為什么修飾了類,對于這個類也是起了一個全局可用的一個作用?
2.越想問題越多,還有就是為什么被Static 修飾的方法可以被類直接引用到?而static 修飾的類也可以被其他的類直接使用,而不依賴于對象。
答 :我們得明確一下
1.static修飾類的方法,表示這個方法和這個類對象沒有關系,只是和這個類有關系
2.static 修飾變量,按照是否靜態(tài)的對類成員變量進行分類可分兩種:一種是被static修飾的變量,叫靜態(tài)變量或類變量;另一種是沒有被static修飾的變量,叫實例變量。兩者的區(qū)別是:
3.對于靜態(tài)變量在內(nèi)存中只有一個拷貝(節(jié)省內(nèi)存),JVM只為靜態(tài)分配一次內(nèi)存,在加載類的過程中完成靜態(tài)變量的內(nèi)存分配,可用類名直接訪問(方便),當然也可以通過對象來訪問(但是這是不推薦的)。
4.好的,是這樣的。static修飾對象 可以全局使用,修飾方法可以不依賴于對象,修飾類,也不用依賴與他的對象,也可以被其他的類直接使用,或者自己進行初始化。
總結
1.嵌套類:內(nèi)部類和靜態(tài)內(nèi)部類
2.內(nèi)部類屬于外部類的成員,必須依賴與外部對象來實現(xiàn),靜態(tài)內(nèi)部類,不依賴,可以自己單獨實現(xiàn)。
3.static 的修飾 變量,類,方法,代碼塊。 共性全局性。變量的話也就是全劇唯一性,會出現(xiàn)多個飲用,但不會出現(xiàn)多個存儲。