13

这与我对此线程中提供的问题的回答有关:内部类是轻量级的吗?

我记得从我的阅读中,如果你只能从一个匿名内部类创建一个对象,因此,如果你想说创建一个ActionListener类并希望从这个类创建多个对象(不使用反射),不使用匿名内部类,而是使用私有内部类或支持类,但人们告诉我我错了。有人可以为我澄清一下吗?请检查链接,因为它包含更多详细信息,但如果有任何不清楚的地方,请询问!

4

2 回答 2

17

您可以创建任意数量的匿名类对象,您可以在代码中的一处创建它们(除非您复制代码)

ExecutorService service = ...
for(int i=0;i<1000*1000;i++) {
   final int finalI = i;
   service.submit(new Runnable() {
      public void run() {
         System.out.println("Task "+finalI+" run.");
      }
   });
}

此代码将创建 100 万个相同类的对象。

于 2011-01-27T18:06:03.540 回答
4

我不清楚。也许如果我们梳理规范,我们会发现内部类应该与普通类一样对待的证据。但是在精神上,内部依赖于外部实例,该类不存在于实例之外。这与基本上是永久存在的“正常”类不同。两个外部实例的两个内部类当然有些相关,由相同的源代码创建,但这并不意味着它们必须相同甚至相等。

有证据表明 Java 设计者打算这样做,即内部类在精神上存在于外部实例的范围内。例如,奇怪的语法outerInstance.new InnerClass()。例如,没有静态变量,内部类没有静态初始化器。在类卸载的讨论[1]中,我们看到这个论点并不真正适用于内部类,可以想象内部类可以被卸载!可以想象,VM 会为每个新的外部实例创建一个新的内部类。

实际上并非如此,内部类确实被视为与普通类相同。但从概念上讲,我总是将它们视为实例私有类。

[1] http://java.sun.com/docs/books/jls/third_edition/html/execution.html#12.7

更新:根据[2]

如果它们...具有相同的二进制名称,则两个引用类型是相同的运行时类型

和 [3]

匿名类的二进制名称(第 15.9.5 节)由其直接封闭类型的二进制名称组成,后跟 $,后跟非空数字序列。

所以一个匿名类有一个二进制名称,因此只有一种运行时类型。该规范向我们保证匿名类的不同实例具有相同的类。

[2] http://java.sun.com/docs/books/jls/third_edition/html/typesValues.html#4.3.4

[3] http://java.sun.com/docs/books/jls/third_edition/html/binaryComp.html#44909

于 2011-01-27T21:14:04.940 回答