2

状況: メイン フォームは、特定のクラスのインスタンスを作成または変更するためにユーザーがパラメーターを入力するテキスト ボックスを含むモーダル jDialog を呼び出します。これを ClassA と呼びます。

ダイアログが既存のインスタンスを変更する必要がある場合、コンストラクターにパラメーターとして渡されます。それ以外の場合、jDialog は ClassA の新しいインスタンスを作成します。

問題: メインフォームはその新しいインスタンスにアクセスする必要があり、メインフォーム全体をパラメーターとして渡し、メソッド呼び出しによってダイアログに新しいインスタンスをプッシュさせるのはクリーンなコードではないと思います。使用可能なスタンドアロン ダイアログは、新しいインスタンスを受け取るために特定のクラス名とメソッドを必要とする 1 つのメイン フォームでのみ使用可能になります。

[OK] ボタンがクリックされた後にメイン フォームが jdialog から新しいインスタンスを取得するようにする方がはるかに論理的です。 getClassAInstance() メソッド (既存のインスタンスが変更されたときにも呼び出すことができます) を呼び出します。このメソッドは、問題の jdialog の新しいインスタンスで「setVisible(true)」メソッドの後に呼び出されます。ダイアログが表示されます。メイン フォームのスレッドは、ダイアログが閉じられるまでスリープ状態になります (モーダルであるため)。[OK] ボタンは jDialog の dispose() メソッドを呼び出し、その次のステートメントは、メインフォームによる jDialog の getClassAInstance() 呼び出しです。

これはコードで同じことです..

ClassAInstanceMakerDialog imd = new ClassAInstanceMakerDialog(this, true);
imd.setVisible(true);
//imd.dispose(); after OK button click
System.out.println(imd.getClassAInstance()); //return a new ClassA instance

//output: whatever ClassA.toString() should return, works fine

質問: 試してみましたが、問題なく動作するようです。しかし、それは良いコードですか?jDialog が破棄された後、メイン フォームが呼び出しを完了する前にガベージ コレクタが ClassA インスタンスを収集したため、getClassAInstance() メソッドが「null」を返す危険性はありますか?

私は英語のネイティブ スピーカーではありません。コードを見たい場合は、お知らせください...

4

3 に答える 3

2

ClassA インスタンスを保持するダイアログ インスタンスのメンバー変数にアクセスすることは完全に合法だと思います。ダイアログ インスタンスは、dispose を呼び出しただけでなく、スコープ外になるまでガベージ コレクションされません。

の署名でイベントハンドラーインターフェイスを定義するソリューションを少し優先します

someThingHappened(ClassA toThisObject)、メインフォーム、または ClassA がそのインターフェイスを実装することに関心のある可能性のあるものを作成して、ダイアログを表示する前にダイアログにリスナーを追加できるようにします。

そうすれば、ダイアログとメイン フォームの間の結合を少し緩めることができます。

于 2012-04-07T18:09:32.580 に答える
1

が呼び出される前に発生したことに関する情報を返すために、が呼び出されIDisposableた後に使用できるプロパティまたはメソッドを含めることは、完全に合理的で適切です。破棄されたオブジェクトのすべてのメソッドが をスローする必要があるというルールをやみくもに強制するのではなく、代わりに、破棄されたオブジェクトでどのメソッドとプロパティが意味をなすか、または意味をなさないかを検討する必要があります。破棄されたオブジェクトにアクセスしようとすると、解放されたリソースを再取得するか、破棄の結果として発生する他の例外をエスケープするよりも優先してスローする必要があります。解放されたリソースがなくてもメソッドまたはプロパティへのアクセスが成功できる場合は、多くの場合、それを許可する必要があります。DisposeDisposeObjectDisposedExceptionObjectDisposedException

于 2012-05-08T22:45:06.320 に答える
1

dispose()JDialogをガベージコレクション用に設定するとは思いませんが、代わりにリソースを解放するだけです。ダイアログはWindow APIに従って再利用できます(JDialog は Window からこのメソッドを継承するため):

この Window、そのサブコンポーネント、および所有するすべての子によって使用されるすべてのネイティブ画面リソースを解放します。つまり、これらのコンポーネントのリソースは破棄され、消費されるメモリは OS に返され、表示不可としてマークされます。

Window とそのサブコンポーネントは、その後 pack または show を呼び出してネイティブ リソースを再構築することにより、再び表示可能にすることができます。再作成された Window とそのサブコンポーネントの状態は、Window が破棄された時点でのこれらのオブジェクトの状態と同じになります (これらのアクション間の追加の変更は考慮されていません)。

注: Java 仮想マシン (VM) 内の最後の表示可能ウィンドウが破棄されると、VM が終了する場合があります。詳細については、AWT スレッドの問題を参照してください。

JDialog オブジェクトへの到達可能な有効な参照がまだ存在している限り、ガベージ コレクションは行われません。ダイアログを破棄するコストは、コードがリソースを再作成するために(非常に)少しの時間を費やす必要があることだと思います。

于 2012-04-07T18:06:44.887 に答える