2009-03-23 8 views
3

私は関数に匿名の内部クラスを渡すと、私はそうのように、そのクラスのメソッド内から現在のスコープ内の変数を参照することができますのsomeMethodは上記の実行された後、今Javaの匿名の内部クラスがスコープを「失う」方法はありますか?

class Caller { 
    private Object callerPrivate; 

    // ... 

    public void someMethod() { 
     final String callerLocal = "Eyes only"; 

     ISomeInterface anon = new ISomeInterface() { 
            public void doSomethingInterfacy { 
             System.out.println(callerPrivate.toString()); 
             System.out.println(callerLocal); 
            } 
            }; 
     // this is some other object that puts ISomeInterfaces in a queue 
     // and makes them doSomethingInterfacy later 
     myCallManager.enqueue(anon); 
    } 
} 

は、呼び出し側と小さなアノニマスのキューは分かれていて、わかっている限り、JVMはすべての参照をまっすぐに保つので、これは常に機能します。

しかし、例えばキューがシリアライズされ、プログラムがシャットダウンして再起動した後、キューがデシリアライズされ、その中のアイテムが実行され、Callerインスタンスが長く消えてしまった場合はどうなりますか?

周囲のオブジェクトと匿名の内部クラスが、anonクラス内の呼び出しがもう動作しないように分離する別の方法がありますか?

答えて

6

(a)ドキュメントがそうであり、(b)シリアル表現が安定していない(開始のために安定した名前を持たない)ため、ローカルクラスをシリアル化しないでください。

インスタンスが外部のフィールドを保持し、最終的なローカルを使用しないようにするには、(静的な)ネストされたクラスまたは外部クラスを使用します。 (Java)シリアル化の場合は、writeReplaceを使用してシリアルプロキシオブジェクトをシリアル化できます。

2

匿名の内部クラスに暗黙のが含まれていることを忘れないでください。このの参照。すなわち、周囲のクラスへの参照である。

したがって、内部クラスをシリアライズすると、外部クラスへの参照があります。 XStreamを使用してシリアル化してXML出力を表示すると、これを明確に見ることができます。

関連する問題