方法本地内部类

时间:2017-02-25 17:02:30

标签: java

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();
         }
      }
 }

当我调用test()时,将创建内部类的次数,它是十次还是只创建一次并创建了10个对象?还要告诉你如何得出这个结论。

2 个答案:

答案 0 :(得分: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这样的控制流语句。它看到内部类并编译一次。另一方面,输出发生在运行时,并遵循控制流语句。

答案 1 :(得分:0)

该类仅创建一次。除了能够查看生成的类文件的实现细节之外,您还可以通过打印类的ID来显示它是相同的Class对象:

    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,因为i不是final,编译器也不能将其视为final。如果变量是final,那么每次迭代时类都是相同的。