4

假设以下场景:

void thisIsCalledManyTimes(){
    // ....
    someObject.executeIfNecessary( new Runnable(){
         void run(){ //do sth here}
    });
}

匿名对象会占用多少空间?我知道每个对象匿名 objrun在其方法查找表中都有一个指向相同实现的指针。

4

4 回答 4

5

Runnable的源代码没有指定任何字段,因此匿名类不会占用比 an 更多的空间Object,但有两个不同之处。内部类具有对外部类实例的隐式引用,因此您需要将其考虑在内。它还将获取final从外部类引用的变量的副本。

于 2012-10-22T13:23:22.017 回答
4

匿名类占用的空间与非匿名类几乎相同。所有对象都保留对它们作为实例的类的引用。

匿名类的唯一不同之处在于它将包含对

  • 外部类实例
  • 使用的任何最终变量的副本。
于 2012-10-22T13:21:57.040 回答
1

的所有实例run确实将共享指向方法查找表的相同“指针”。但是,对象的精确大小取决于它的内容run...上面的内容。编译器生成的匿名类提供了存储方法引用的变量的空间,以及存储对封闭类对象的run引用的空间。this

例如,

private String name;

void thisIsCalledManyTimes(){
    final int value1 = 123;
    final double value2 = 456.789.
    someObject.executeIfNecessary( new Runnable(){
         void run(){
             System.out.println(name);   // Referenced through the enclosing "this"
             System.out.println(value1); // Variable will be inserted by the compiler
             System.out.println(value2); // Variable will be inserted by the compiler
         }
    });
}

在对象中保留空间来存储value1,value2this; 匿名对象的每个实例都将获得这些变量的副本。

于 2012-10-22T13:22:03.787 回答
0

使用分析器检查您的班级实例的大小。它相当小,因为没有属性 - 它与 java.lang.Object 的实例一样大。这取决于 JVM 版本。

如果您需要提高效率,请执行以下操作:

void thisIsCalledManyTimes(){
// ....
   if (someObject.isItNecessary()) {
     someObject.execute( new Runnable(){
         void run(){ //do sth here}
     });
   } 

}

但是,我不会像这个那样太在意这个。

于 2012-10-22T13:24:54.747 回答