Рассмотрим следующее:
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
(особенно полезно в этом случае, когда существует "конфликт имен"
То же самое и при создании анонимного внутреннего класса: созданный анонимный внутренний класс содержит ссылку на внешний класс, поэтому при объявлении предиката внутри метода (анонимный метод-локальный внутренний класс) мы по-прежнему можем получить доступ внутри внутреннего класса к переменные внешнего класса без необходимости объявлять их окончательными (в то время как мы должны для переменных, переданных как параметры метода.
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 я обычно объявляю в своем интерфейсе функции и предикаты, что позволяет мне использовать полезные функции Guava, такие как Maps.uniqueIndex(...)
.
public interface AlternativeNameable {
String getAlternativeName();
Function<AlternativeNameable,String> GET_ALTERNATIVE_NAME = new Function<AlternativeNameable,String>() {
@Override
public String apply(AlternativeNameable input) {
return input.getAlternativeName();
}
};
}
Итак, вы можете спросить себя, в чем мой вопрос? Вот:
При объявлении анонимного класса в качестве константы интерфейса (см. мой последний пример кода), на какой внешний класс ссылается анонимный внутренний класс?