3

全体的な問題は、コンポーネント (ボタン、メニュー項目など) のオブジェクトが JFrame、JPanel、JMenu などに追加された場合、Java はそのオブジェクトをどこに格納するのかということです。ドキュメントを掘り下げているときに、それらがリストに格納されていると言っているのを見ましたが、Oracleのドキュメントを掘り下げて、その実装に関する特定の情報を見つけようとしています。すでにそれを理解している人は、私が理解するのを助けることができますか?

Oracle の Java チュートリアルを進めていたときに、同じ型のオブジェクトを作成するために単一の識別子が再利用されていることに気付きました。たとえば、これは 2 つの別個のボタンを作成します。

JPanel buttonPnale = new JPanel("Making some buttons");
JButton buttonMaker;

buttonMaker = new JButton("Left button", blueBurstIcon);
buttonPanel.add(buttonMaker);

buttonMaker = new JButton("Right button", orangeBurstIcon);
buttonPanel.add(buttonMaker);

通常、私はこれを行う必要があると思っていたでしょう:

JButton buttonOne = new JButton("Left button", blueBurstIcon);
JButton buttonTwo = new JButton("Right button", orangeBurstIcon);

個別のオブジェクトごとに個別の識別子を作成します。

明らかに、コードの最初のスニペットのオブジェクトはどこかに保存されています。どこにあるかを調べようとしています。それらがコピーされるのは、.add を呼び出すときでなければなりませんが、どこにコピーされますか? それらが JPanel に追加された場合、それらは JPanel に含まれるデータ構造にコピーされますか? または、JPanel が追加された JFrame の一部のデータ構造に?

4

5 に答える 5

3

は、クライアント コンポーネント (この場合はあなたの ) の内部リストを維持するJPanelから継承します。このリストは、次のソース コードにあります。java.awt.ContainerJButtonContainer

/**
 * The components in this container.
 * @see #add
 * @see #getComponents
 */
private java.util.List<Component> component = new java.util.ArrayList<Component>();

コンポーネントは、 のメソッドから呼び出されるメソッドによって追加されprotected void addImpl(...)ます。public Component add(Component comp)Container

だから全部プライベート。あなたはそれを見るべきではありません。;-)

于 2013-06-24T16:35:30.303 に答える
3

ほとんどの Swing コンポーネントには、子のリストが含まれています。フレームにはそのようなリストがあり、ボタンで呼び出すとすぐにadd()、ボタンがそのリストに追加されます。

コピーは作成されていません。リスト内の (名前のない) 参照と名前付き参照の両方が、buttonMakerメモリ内の同じインスタンスを指しています。一部の言語では、「エイリアス」を呼び出しbuttonMakerて、それが実際にはオブジェクトまたはインスタンス自体ではなく、インスタンスへのアクセスを提供するものの名​​前であるという事実を強調しています。

に新しい参照を割り当ててbuttonMakerも、フレームのリスト内のボタンには影響しません。

これは、Java が常に誰か (参照buttonMakerまたはリスト) がボタンを参照していることを意味するため、ボタンはガベージ コレクションされません。

于 2013-06-24T16:04:08.773 に答える
2

さて、あなたの質問はいいものです..しかし、はい、初心者の質問です..

とは異なりC、 C でJava知られている基本的なメモリ ブロックをトラバースする機能を提供しませんpointers。しかし、はい、概念は安全なままです。

これは、 について話すとMulti-Threading、そのような機能 (Java でポインタを使用する) によってメモリの衝突が発生するためです。そのため、 によって自動的に処理されJVMます。Javaをthread-safe言語にすること。

それとは別に、あなたが例で求めているのは...

2 つのボタンが作成されるのはなぜですか?

したがって、コードを詳細に見ると、ツリー構造に従います。つまり、 がJPanelツリーの一番上にあり、それに子を追加するだけです。したがって、すべての子ノードを追跡しています。ただし、次のコードを記述するだけの場合:

JPanel buttonPnale = new JPanel("Making some buttons");
JButton buttonMaker;

buttonMaker = new JButton("Left button", blueBurstIcon);
buttonMaker = new JButton("Right button", orangeBurstIcon);
buttonPanel.add(buttonMaker);

次に、buttonMaker はボタンの古いレコードを失います。新しく作成したボタンを追加します。

覚えておいてください、それはツリー構造に従い、ポインタ (メモリ管理) は完全にJVM

于 2013-06-24T16:10:53.487 に答える
0

最初のbuttonMakerを追加すると、buttonMaker は別の JButton を参照します。最初のbuttonPanel.add(..)メソッド呼び出しは、その後、その buttonMaker 変数が何に設定されたかには関係ありません。これは、この変数のスコープがメソッド レベルのみにあるためです。その変数は、2 番目のbuttonPanel.add(..)呼び出しには存在しません

于 2013-06-24T16:00:17.187 に答える