1. 程式人生 > >Java 靜態內部類 與 非靜態內部類的區別?什麼時候用靜態內部類,又是什麼時候用非靜態內部類?

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)生命週期不一樣:靜態內部類隨著外部類的載入而載入,而不是隨著外部類物件的產生而產生。

    外部類例項 與靜態內部類例項是沒有關係的。

    外部內部類例項對應著不同的非靜態內部類例項。