2017-02-25 74 views
-1
class Outer 
{ 
    int outer_x = 100; 
    void test() 
    { 
     for(int i=0; i<10; i++) 
     { 
      class Inner 
      { 
       void display() 
        { 
         System.out.println("display: outer_x = " + outer_x); 
        } 
       } 
      Inner inner = new Inner(); 
      inner.display(); 
     } 
     } 
} 

多少次,當我打電話測試(內部類將被創建),它是十次或只有一次,10對象被創建?還有告訴你怎麼想出了這個結論。方法本地內部類

+0

創建了10個對象,您可以檢查調試時創建的對象的哈希碼。 – suiwenfeng

+0

[Java:對象的散列函數]的可能重複(http://stackoverflow.com/questions/7422998/java-hash-function-for-objects) – suiwenfeng

+0

內核類在編譯時創建一次。 – EJP

回答

1

僅當您的代碼被編譯時,類@Inner才被創建,因爲@EJP評論。查看編譯輸出時可以輕鬆驗證這一點。

我創建了一個名爲Outer.java的.java文件,並對其進行簡單編譯。結果是兩個.class文件。

Compilation output

你可以看到,創建了一個名爲Outer.class一個類文件,但也被稱爲Outer$1Inner.class類文件,這簡直是你的本地類編譯器。在這裏,Java使用$1來標記內部的匿名類。

添加main方法,並呼籲new Outer().test();你可以看到輸出確實是10日線,這意味着10個實例Inner創建。您可以輕鬆地通過添加hashCode()某處輸出像這樣

System.out.println("display: outer_x = " + outer_x + " --> " + hashCode()); 

這給下面的輸出驗證這一點:

display: outer_x = 100 --> 1704856573 
display: outer_x = 100 --> 705927765 
display: outer_x = 100 --> 366712642 
display: outer_x = 100 --> 1829164700 
display: outer_x = 100 --> 2018699554 
display: outer_x = 100 --> 1311053135 
display: outer_x = 100 --> 118352462 
display: outer_x = 100 --> 1550089733 
display: outer_x = 100 --> 865113938 
display: outer_x = 100 --> 1442407170 

不同的散列碼的意思是不同的實例。

現在發生這種情況的原因是,編譯器在收集類時並不關心像for這樣的控制流語句。它看到內部類並編譯一次。另一方面,輸出發生在運行時間並遵循控制流程語句。

0

該類只創建一次。還有的能夠看到生成的類文件的實現細節,你也可以說這是同一個類的對象通過打印類的ID:

for (int i = 0; i < 10; i++) { 
     class Inner { 

      void display() { 
       System.out.println("display: outer_x = " + outer_x); 
      } 
     } 
     Inner inner = new Inner(); 
     System.out.println(System.identityHashCode(inner.getClass())); 
     inner.display(); 
    } 

這每次打印相同的編號。

但是,如果你編碼它,使得每次在循環中創建一個行爲不同的類?

for (int i = 0; i < 10; i++) { 
     class Inner { 

      private int field = i;    

      void display() { 
       System.out.println("My field = " + field); 
      } 
     } 
    } 

這不會編譯,因爲的Java只會創建一個類,因此它必須是每次都一樣。

的編譯錯誤是:local variables referenced from an inner class must be final or effectively final,因爲ifinal,也不是編譯器可以把它當作如果final。如果該變量是最終的,那麼每個迭代類將是相同的。