2017-02-25 57 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。如果该变量是最终的,那么每个迭代类将是相同的。