最近在閱讀一些開源框架的源碼,發現了static class這樣的東西,似曾相識,可是又有點搞不清楚它確切的含義,今天把這個事情搞搞清楚。java
關於java當中的static,你們應該都有着必定的瞭解。多數時候使用它來修飾class當中的一個屬性或者一個方法,這樣的話,對這個屬性或者方法的調用就能夠不依賴於class的某一個實例了。框架
可是,若是用static來修飾一個內部class,它又表明着什麼樣的含義呢?看起來應該是跟修飾屬性和方法表明着差很少的意思。spa
那麼咱們還須要先複習一下非靜態內部類的使用。對象
public class OutClass {
private int value = 100;
public class InnerClass {
public void println(){
System.out.println("I am an inner class!" + " the value of out obj is " + value);
}
}
}編譯器
public class TestInner {
public static void main(String[] args){
OutClass.InnerClass innerObj = new OutClass().new InnerClass();
innerObj.println();
}
}源碼
請注意一下,我標註成紅色的部分,這裏有幾個知識點:編譯
一、在InnerClass的定義當中,他是一個public的類,可是,即便如此,咱們在定義變量類型的時候,還必需要寫上OutClass.InnerClass,這裏,從邏輯上是說得通的,咱們須要知道這個內部類到底是來自哪裏。由於咱們其實能夠定義一個也叫InnerClass的頂層類,因此,若是不加上OutClass.,會讓編譯器無所適從的。class
二、在實例化內部類的時候,必須依賴於一個外部類的實例,這裏和非static的屬性和方法的使用是同樣的,非static的內部類、屬性、方法,都必須依賴於一個外部類的實例。變量
三、內部類當中能夠隨意訪問外部類的屬性和方法,關於這個問題,咱們能夠這麼理解,在構造內部類的時候,java編譯器,會把一個外部類對象交給內部類對象來使用,這一點其實和第二點是息息相關的。開源框架
下面咱們再看一下靜態內部類的使用:
public class OutClass {
public static class InnerClass {
public void println(){
System.out.println("I am an static inner class!");
}
}
}
public class TestInner {
public static void main(String[] args){
OutClass.InnerClass innerObj = new OutClass.InnerClass();
innerObj.println();
}
}
這一次,咱們把InnerClass變成了static的,那麼在實例化的時候,就能夠不依賴於OutClass的實例了,static的語義的一致性在這裏獲得了充分的體現。那麼因爲內部類的實例化,並不依賴於外部類的實例,因此,內部類也沒法訪問外部類的任何非靜態的屬性和方法。
那麼還有最後一個問題,咱們知道,雖然咱們不依賴於實例,來訪問類的靜態屬性和方法,可是用實例來訪問,其實也是能夠的。
可是,我仍是要經過外部類的實例,來建立一個內部類的實例,這樣能夠嗎?
public class TestInner {
public static void main(String[] args){
OutClass outObj = new OutClass();
OutClass.InnerClass innerObj = outObj.new InnerClass();
innerObj.println();
}
}
紅色的部分會報錯,而給出的錯誤信息是:Qualified new a static class(有資格來new一個靜態類),大概意思是,你能直接new一個靜態內部類,就別經過外部類的實例了。
這裏實際上是咱們今天的結論,static的語義,在用於class的時候,和它用於屬性和方法的時候,語義是大致上相同的。惟一的不一樣點,static在用於class的時候,是沒法經過外部類實例來new一個靜態內部類的。到底是基於什麼樣的考慮,有了這樣的限制,暫時不知道~~~