2012-03-19 2 views
6

私はJPanelを継承するクラスを持っています。そのコンストラクタでは、私はthisを他のメソッドに渡しています。主にjpanelオブジェクトをjpanel内のコンテナ/コントロール(ほかのオブジェクト)にリスナーとして追加します。 Netbeansはこれらの呼び出しに対してleaking this in constructorという警告を表示しているので、コンストラクタから呼び出される他のメソッドにそれらを入れました。症状を取り除くこれをコンストラクタにリークする - リスナーと "this"が必要なその他のメソッドを適切に追加する場所

class Foo ... { 
    public Foo() { 
     initComponents(); 
     initListeners(); 
    } 

    protected void initListeners() { 
     tabX.addChangeListener(this); 
    } 

:後

class Foo ... { 
    public Foo() { 
     initComponents(); 
     tabX.addChangeListener(this); // <- netbeans complains here 
    } 

:前

。しかし、私はnetbeansが警告を表示する理由を修正するのは間違いです。
JPanel派生クラスでこの種の初期化を実行する適切な場所はどこですか?

+0

あなたはメソッドのシグネチャを投稿することができ、あなたが – Woot4Moo

+0

、これはあなたがhttp://stackoverflow.com/questions/3921616/java-leaking-this-in-constructor – Chikei

+0

[Javaのに役立つかもしれない「修正」 - 漏れましたこれはコンストラクタ](http://stackoverflow.com/q/3921616/1048330) – tenorsax

答えて

0

私は、あなたはおそらく、いくつかの他の構成要素(例えばJFrameJApplet、別のJPanel、など)にごJPanel拡張機能を追加していると仮定しています。あなたは、そのパネル内のサブコンポーネントにパネルを追加する必要性と、パネルが聴く必要がある「他のオブジェクト」との間に少しのミックスがあると述べました。おそらく、あなたのJPanelエクステンションをそのエクステンションのクラス定義外にあるJFrameまたは他の親コンポーネントに追加する場所の近くの「他のオブジェクト」にパネルを追加する方が良いでしょう。

しかし、あなたのパネルが聴かなければならないパネルのサブコンポーネントについては、サブクラスがJPanelエクステンションクラス定義外のオブジェクトには表示されない限り、あなたがやっていることは問題ないと思います。この警告は、あなたがやっていることは安全ではないかもしれないが、最終的にパネルがガベージコレクトされたときに、それが所有するすべてのサブコンポーネントも保持するリスナーリスト拡張子はJPanelです。この事実のために、私はadd*Listener(this)をあなたのJPanelという拡張子を持つ適切な名前のプライベートメソッドに入れて、あなたのコンストラクタから呼び出すことはいいと思います。

もう1つの選択肢は、Eclipseを使用して、その警告をもう表示しないようにすることです(完全に冗談です)。

0

この警告の理由は、コンストラクタが終了せずオブジェクトが完全に初期化されていない間にこれを渡してしまうことです。あなたがコンストラクタの終わりにそれを使用しても、あなたのクラスが拡張され、まだ実行されるサブクラスのコンストラクタが存在する可能性があります。 スイングはシングルスレッドであり、オブジェクトが初期化された後にのみイベントがリスナーに渡されるので、これは安全です(リスナーとしてオブジェクトを登録する)。

+1

シングルスレッド環境であっても、プログラミングが悪いです。 –

2

あなたのクラスにあまりにも多くのことを尋ねるより大きな問題があるのでしょうか?クラスには主な目的が1つあり、ビューにはビューが関与している必要があります。それがモデルや制御機能を持たせてcohesionを失うと、デバッグや拡張が不可能ではないにしても困難な神オブジェクトを作成するリスクがあり、couplingが増加する可能性があります。ですから、あなたのGUIやビューのクラスは、曖昧にするとでなく、もリスナークラスでなければなりません。言い換えれば、GUIクラスがリスナー・インターフェースも実装するのは正当な理由と多くの悪い理由はありません。

最高の解決策:GUIクラスにリスナーを実装しないでください。代わりに、匿名の内部クラス、またはプライベート内部クラスを使用するか、または複雑な場合、または将来コードを拡張および/または変更する予定の場合は、単独のリスナークラスを使用してください。私は従っていないことを確認

+1

スタンドアロンのリスナーの場合は、[* package-private *](http://docs.oracle.com/javase/tutorial/java/javaOO/accesscontrol.html)アクセスが便利です。 – trashgod

+1

しかし、インスタンスがコンストラクタで作成されている場合、匿名の内部クラスは 'this'の漏れの問題を解決しません。これは暗黙のうちに「今」が漏れているので、問題を見つけにくくするだけです。 –

関連する問題