Java 靜態內部類 與 非靜態內部類的區別?什麼時候用靜態內部類,又是什麼時候用非靜態內部類?
Java中內部類載入時間:一般是隻有運到了才會初始化,而不是外部內載入的時候(不管是靜態還是非靜態內部類)。
注意到一個問題:
內部類只有是靜態的,其內部類中才能有靜態屬性和靜態方法;
如果內部類非靜態的,其內部類不能有靜態屬性和靜態方法。
例子:
原因是什麼呢?public class OutClass { <span style="white-space:pre"> </span>static{ <span style="white-space:pre"> </span>System.out.println("OutClass static{ }"); <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>static int temp =1; <span style="white-space:pre"> </span>public static void main(String[] args) { <span style="white-space:pre"> </span>OutClass OutClass = new OutClass(); <span style="white-space:pre"> </span>OutClass.new InnerClazz(); <span style="white-space:pre"> </span>StaticInnerClazz claxxClazz = new OutClass.StaticInnerClazz(); <span style="white-space:pre"> </span>claxxClazz.b = 6; <span style="white-space:pre"> </span>StaticInnerClazz claxxClazz2 = new OutClass.StaticInnerClazz(); <span style="white-space:pre"> </span>System.out.println(claxxClazz2.b ); <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>public OutClass(){ <span style="white-space:pre"> </span>System.out.println("OutClass"); <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>class InnerClazz { <span style="white-space:pre"> </span>/*static int b = 0;// 編譯不通過 <span style="white-space:pre"> </span>static{ //編譯不通過 <span style="white-space:pre"> </span>System.out.println(); <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>public static void show() { <span style="white-space:pre"> </span>System.out.println(); <span style="white-space:pre"> </span>}*/ <span style="white-space:pre"> </span>public InnerClazz() { <span style="white-space:pre"> </span>temp = 2; <span style="white-space:pre"> </span>System.out.println("InnerClazz()"); <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>static class StaticInnerClazz { <span style="white-space:pre"> </span>int a = 1; <span style="white-space:pre"> </span>static int b = 0;// 編譯通過 <span style="white-space:pre"> </span>static { // 編譯通過 <span style="white-space:pre"> </span>System.out.println("StaticInnerClazz static{ }"); <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>public void show() { <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>public StaticInnerClazz() { <span style="white-space:pre"> </span>temp= 1; <span style="white-space:pre"> </span>System.out.println("StaticInnerClazz()"); <span style="white-space:pre"> </span>} <span style="white-space:pre"> </span>} }
靜態內部類與非靜態內部類的區別:
1)靜態內部類可以有靜態成員(方法和屬性),而非靜態內部類則不能有靜態成員(成員或屬性)
2)靜態內部類只能夠訪問外部類的靜態成員和靜態方法,而非靜態內部類則可以訪問外部類的所有成員(方法和屬性)
3)例項化一個非靜態的內部類的方法:
OutClass.InnerClass innerClass = new OutClass().new InnerClass();
4)例項化一個靜態內部類的方法:
不依賴於外部類的例項,直接例項化靜態內部類物件:
OutClass,InnerClass innerClass = new OutClass.InnerClass();
總結:
1)內部類相對於外部類來說,前者是後者的方法,所以當前者是static修飾的時候,在前者中不能訪問後者中的非static屬性和方法;
相反,當前者是非static修飾的時候,前者可以訪問後者中的任何成員。
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
什麼時候用靜態內部類?什麼時候用非靜態內部類?
1)首先要弄清楚:為什麼要用內部類?用內部類是因為內部類與所在外部類有一定的關係,往往只有該外部類呼叫此內部類,
所以沒有必要專門用一個Java檔案存放這個類。
2)生命週期不一樣:靜態內部類隨著外部類的載入而載入,而不是隨著外部類物件的產生而產生。
外部類例項 與靜態內部類例項是沒有關係的。
外部內部類例項對應著不同的非靜態內部類例項。