2017-08-15 3 views
0
final ArrayAdapter adapter = new ArrayAdapter(...); 
listView.setOnItemClickListener(new AdapterView.OnitemClickListener(){ 
    @Override 
    public void onItemClick(AdapterView<?> parent,View view,int position,long id){ 
     Word word = adapter.getItem(position); 
    } 
}); 

匿名の内部クラスが「final」と宣言されるべき「adapter」オブジェクトを呼び出す理由を理解できませんか?これはルールですか?私はそれを覚えていますか? finalと宣言された変数が変更なしで参照を保存することはわかっています。しかし、上記の例では、参照の変更はありません。最終的なオブジェクトに対してメソッドを呼び出すだけです。外部オブジェクトがfinalで宣言されたときに匿名内部クラスが外部オブジェクトを呼び出す理由

+0

は、効果的な最終 – Jerry06

+0

匿名内部クラスは、シンプルで効果的な方法で、いくつかの厄介な問題を解決するためです。また、最終クラスを拡張することができない間に、アダプタクラスによってイベントが処理されるときに、より効率的なコードを作成することもできます。 – Tehmina

答えて

1

これは、リスナーでアダプタにアクセスしようとしているためです(また、発生するタイミングもわからないため)。したがって、リスナーからコールバックを取得するたびに参照が同じになるため、最終的に宣言する必要があります。関数が破棄されると、関数内で宣言された非最後の参照もすべて破棄されます。次に、リスナーで後でアクセスしようとする参照はもう存在しません。

したがって、2つの解決策があります。最終的に宣言し(関数が「破棄」された後でも参照を保持する)、グローバルに宣言します。

+0

この関数はsetonItemClickListenerメソッドを示しますか?どのように私はこの関数が参照の破壊後に使用されないことを知っていますか? – GeniusL

+0

つまり、setOnItemClickListenerを使用すると、コンポーネントにビヘイビアを "割り当てる"ようになります。関数を呼び出すたびに、新しい参照が作成され、関数から出ると参照が破棄されます。あなたが最終的にそれをしたくない場合の解決策は、ithatが変数をグローバルにして参照を保持するので、(onCreateの外でも)関数の外にアダプタを宣言することです。リスナーの外でその変数を使用する必要がない場合は、リスナー内で変数を宣言することもできます –

+0

アダプタがまだ存在するときにonItemClickListenerメソッドを呼び出すことはできますか?だから私はそれを最終として宣言します。 あなたは関数を呼び出すたびに、誰が引用する新しい参照を作成するのでしょうか? – GeniusL

0

内部クラスで使用される変数を宣言することは、逆参照が別のスレッドで実行される可能性があります。これらを作成しないとfinalはこれらをスタックからヒープにシフトする必要があり、クロージャを提供します。どうやらユーザーはそれに反対しています。

はここを参照してください:それはhttp://people.csail.mit.edu/gregs/ll1-discuss-archive-html/msg04030.html

関連する問題