2011-10-31 18 views
4

は、以下のリンクから覗いあり:、具体的にGLSurfaceView code sample匿名クラスは外部参照を有効にしますか?

、そのページ上の2番目のコードブロックに次の関数を見てください:ここで私を混乱させる

public boolean onTouchEvent(final MotionEvent event) { 
    queueEvent(new Runnable() { 
     public void run() { 
      mRenderer.setColor(event.getX()/getWidth(), event.getY()/getHeight(), 1.0f); 
     } 
    }); 

    return true; 
} 

何アノンのRunnableは非常に多くを参照することです局所的な "event"オブジェクトですが、実際には完全に別のスレッドでrunnableを実行してしまいます。あるいは、ローカルなref-within-anon-classの使い方の種類が実際には "イベント"オブジェクトのリファレンスカウントで+ 1を実行するので、anon Runnableがまだ呼吸している限り、周囲に固執するでしょうか?

また、MotionEvenが最終版と宣言されているという事実は、これと関連がありますか?

P.S. (私の主な関心事ではありませんが)関連する質問として、 "イベント"の代わりに(またはそれに加えて)匿名クラスの内部で "int x"のようなプリミティブを参照するとどうなりましたか? (プリミティブのrefカウントを+1することはできないので見てください)。

答えて

3

Javaはガベージコレクションを行うために参照カウントを使用しません。私は、JVMがこの種のクロージャをどのように実装しているかについて多くは分かっていませんが、匿名クラスのインスタンスにはeventへの参照が含まれていると推定できます。その場合、匿名のRunnableが生存している限り、それが参照するものはすべて生きています(そして、それらが参照しているものはすべて生きているなどです)。

プリミティブ型は、フィールドに直接コピーされます。したがって参照されてからガベージコレクトされる限り、生きる必要のあるものへの「参照」はありません。それらはそれらを含むオブジェクトの一部に過ぎません。 int 287に「新しい参照を作る」たびに、別の参照を持つ287を格納する場所があるわけではなく、別のメモリワードが287を格納しているだけです。もともとあなたの出身を解雇してしまったのです。あなたは完全に独立しています。

2

変数がfinal宣言されている場合にのみ変数を参照することができ、スレッドは参照を保持してガベージコレクションを停止します。

4

はい、Runnableは、MotionEventへの参照を保持します。 MotionEventは、Runnableが収集可能になるまでガベージコレクションできません。

finalローカル変数のみが内部クラスから参照できます。

ところで、参照カウントが使用されているとは限りません。ほとんどのガベージコレクタは、現在、参照カウントを使用していません。

+1

内部クラスは、囲むクラスで宣言された(非最終的な)インスタンス変数と静的変数を参照することもできます。 –

関連する問題