次のことを考慮してください。
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
(「ネーミングコリジョン」がある場合に特に役立ちます)。
匿名内部クラスを作成する場合も同じです。作成された匿名内部クラスは外部クラスへの参照を保持します。これが、メソッド内で述語を宣言するときに(匿名メソッド-ローカル内部クラス)、内部クラス内で引き続きアクセスできる理由です。アウタークラスの変数は、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);
}
};
}
}
そして最後に、インターフェイスで定数を宣言できます。これは、暗黙的にpublicstaticfinalとマークされています。オブジェクトは定数にすることができます。したがって、匿名の内部クラスとして作成されたオブジェクトは、インターフェイスの有効な定数です。
たとえば、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();
}
};
}
だからあなたは私の質問は何ですか?ここにあります:
匿名クラスをインターフェース定数として宣言する場合(私の最後のコードサンプルを参照)、匿名内部クラスはどの外部クラスへの参照を保持しますか?