这与我对此线程中提供的问题的回答有关:内部类是轻量级的吗?
我记得从我的阅读中,如果你只能从一个匿名内部类创建一个对象,因此,如果你想说创建一个ActionListener
类并希望从这个类创建多个对象(不使用反射),不使用匿名内部类,而是使用私有内部类或支持类,但人们告诉我我错了。有人可以为我澄清一下吗?请检查链接,因为它包含更多详细信息,但如果有任何不清楚的地方,请询问!
这与我对此线程中提供的问题的回答有关:内部类是轻量级的吗?
我记得从我的阅读中,如果你只能从一个匿名内部类创建一个对象,因此,如果你想说创建一个ActionListener
类并希望从这个类创建多个对象(不使用反射),不使用匿名内部类,而是使用私有内部类或支持类,但人们告诉我我错了。有人可以为我澄清一下吗?请检查链接,因为它包含更多详细信息,但如果有任何不清楚的地方,请询问!
您可以创建任意数量的匿名类对象,您可以在代码中的一处创建它们(除非您复制代码)
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 万个相同类的对象。
我不清楚。也许如果我们梳理规范,我们会发现内部类应该与普通类一样对待的证据。但是在精神上,内部类依赖于外部实例,该类不存在于实例之外。这与基本上是永久存在的“正常”类不同。两个外部实例的两个内部类当然有些相关,由相同的源代码创建,但这并不意味着它们必须相同甚至相等。
有证据表明 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