请考虑以下事项:
public class OuterClass {
private String attribute = "outer";
class InnerClass {
private String attribute = "inner";
public doSomething() {
System.out.println(this.attribute);
System.out.println(OuterClass.this.attribute);
}
}
}
InnerClass不是静态的,必须针对它的外部类的实例创建。
new OuterClass().new InnerClass()
常规的内部类包含对创建它的外部类的引用,可以使用Outer.this.myAttribute
访问(在这种情况下特别有用,其中有一个“命名” colision“
创建匿名内部类时,它是相同的:创建的匿名内部类包含对外部类的引用,这就是为什么在方法内部声明谓词(匿名方法 - 本地内部类)时,我们仍然可以访问innerclass,外部类的变量,而不必将它们声明为final(而我们应该将变量作为方法参数传递。
public class OuterClass {
// Do not need to be final because the innerclass keeps a reference to the outerclass
// even if it's an anonymous innerclass, it's still an innerclass
private String classAttribute = "classAttribute";
public Runnable doSomething() {
// Should be final because the variable lives on the stack and the reference to this object
// must be copied so that the String object is still accessible when the stack frame is destroyed
final String localVar = "localVar";
return new Runnable() {
@Override
public void run() {
System.out.println(classAttribute);
System.out.println(localVar);
}
};
}
}
最后,我们可以在接口中声明常量,这些常量隐式标记为public static final。对象可以是常量。 因此,作为匿名内部类创建的对象是接口的合法常量。
例如,当使用Guava时,我通常在我的接口函数和谓词中声明,这允许我利用像Maps.uniqueIndex(...)
这样有用的Guava函数。
public interface AlternativeNameable {
String getAlternativeName();
Function<AlternativeNameable,String> GET_ALTERNATIVE_NAME = new Function<AlternativeNameable,String>() {
@Override
public String apply(AlternativeNameable input) {
return input.getAlternativeName();
}
};
}
所以你可能会问自己我的问题是什么?这是:
当声明一个匿名类作为接口常量时(参见我的上一个代码示例),匿名内部类在哪个外部类上保存对引用的引用?
答案 0 :(得分:4)
接口always implicitly have the modifiers public static final
中定义的字段。它是一个常数,因此它没有相关的外部类。
此外,member types of interfaces are implicitly public and static也适用于匿名类。
答案 1 :(得分:2)
接口的内部类是隐式静态的,因此不需要引用外部类。