【发布时间】:2016-04-09 20:46:12
【问题描述】:
当从实例方法返回一个没有对其封闭类的引用的匿名类时,它具有对this 的引用。为什么?
考虑以下代码:
package so;
import java.lang.reflect.Field;
public class SOExample {
private static Object getAnonymousClassFromStaticContext() {
return new Object() {
};
}
private Object getAnonymousClassFromInstanceContext() {
return new Object() {
};
}
public static void main(String[] args) throws NoSuchFieldException, SecurityException {
Object anonymousClassFromStaticContext = getAnonymousClassFromStaticContext();
Object anonymousClassFromInstanceContext = new SOExample().getAnonymousClassFromInstanceContext();
Field[] fieldsFromAnonymousClassFromStaticContext = anonymousClassFromStaticContext.getClass().getDeclaredFields();
Field[] fieldsFromAnonymousClassFromInstanceContext = anonymousClassFromInstanceContext.getClass().getDeclaredFields();
System.out.println("Number of fields static context: " + fieldsFromAnonymousClassFromStaticContext.length);
System.out.println("Number of fields instance context: " + fieldsFromAnonymousClassFromInstanceContext.length);
System.out.println("Field from instance context: " + fieldsFromAnonymousClassFromInstanceContext[0]);
}
}
这是输出:
Number of fields static context: 0
Number of fields instance context: 1
Field from instance context: final so.SOExample so.SOExample$2.this$0
每个方法,虽然看似调用相同的代码,却做着不同的事情。在我看来,实例方法返回的是嵌套类,而静态方法返回的是静态嵌套类(作为静态成员,它显然不能引用this)。
鉴于没有对封闭类的引用,我看不出这样做的好处。
幕后发生了什么?
【问题讨论】:
-
这就是闭包不这样做的原因。我假设这简化了实现以不优化
this或外部类(如果实际上不需要)。 -
你是什么意思 鉴于没有引用封闭类的事实
-
@RobertBain 引用仍然存在,它与您的匿名类非常相似,该类具有初始化为外部实例的
private SOExample foobar成员 - 即使您没有任何代码,它仍然存在使用它。对外部实例的引用是存在的,因为 Java 规范说就是这样 - 即使没有使用它的代码,也没有省略引用的特殊情况。 -
所有本地类都会发生这种情况,而不仅仅是匿名类。老实说,我看不出让在非静态内容中创建的本地类被允许访问外部类的其他成员有什么奇怪的(并且使它可能需要引用来保存外部类的特定实例) .在静态上下文中创建的本地类对实例一无所知,因此它们不需要字段来保存此类实例。
标签: java anonymous-class