2011-01-27 67 views
14

这是关于我的回答在这个线程提供了一个问题:Are Inner Classes lightweight?重新匿名内部类的多个实例

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

+0

谢谢,我想我明白,但是这需要创建多个类 - 如果我理解正确。问题是给出一个匿名内部类的代码,你可以创建它的多个对象实例吗?而且我不是说使用循环,因为再次,这将创建多个类--- oops,您的评论去哪儿了? – 2011-01-27 18:04:57

+1

我认为你的意思是它的类的多个实例?一个对象本身就是一个实例 – 2011-01-27 18:05:57

+1

@Hovercraft,不能在注释中放置可读代码。 ;) – 2011-01-27 18:06:47

回答

16

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

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."); 
     } 
    }); 
} 

此代码将创建同一类1个亿个对象。

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