- - PR -
別クラスのメソッドを使用する場合についての質問
| 投稿者 | 投稿内容 | ||||
|---|---|---|---|---|---|
|
投稿日時: 2003-11-18 19:18
私の場合、このような事態に陥りそうなとき、FactoryMethodの使用を検討します。
| ||||
|
投稿日時: 2003-11-19 10:06
かずくんさん、ご意見ありがとうございました。
FactoryMethodに関しての知識が乏しいので、勉強してかずくんさんにいただいたコードを見直そうとおもいます。 ところで、例えば下記のような場合、クラスA、B、Cがあります。 クラスAはクラスBを作成しています。 クラスBはクラスCを作成しています。 クラスCはクラスAのメソッドを実行しています。 クラスCまでが作成された時には、クラスAは全部で3つあると考えるのでしょうか? 一つは元々のクラスA、二つ目はクラスBの中でのクラスA、三つ目はクラスCの中でのクラスA。 もしも、3つあるのだとするとメモリー上にはまったく同じクラスAが3つ存在する事になるのでしょうか? public class Class_A { //元々のクラスA boolean blnA = false; void makeClassB(){ Class_B clsB = new Class_B(this); //クラスB作成 } void A_Method(){ blnA = true; } } public class Class_B { Class_A clsA;//クラスBの中でのクラスA public Class_B(Class_A cls) { clsA = cls; } void makeClassC(){ Class_C clsC = new Class_C(clsA); //クラスC作成 } } public class Class_C { Class_A clsA; //クラスCの中でのクラスA public Class_C(Class_A cls) { clsA = cls; } void doClsAMethod(){ clsA.Method(); //クラスAのメソッドを実行 } } うーん、説明しながら我ながら良くわからない説明だ・・・・ | ||||
|
投稿日時: 2003-11-19 10:34
unibon です。こんにちわ。
Java はインスタンスを生成するためには必ず new しないといけないので、 ソースコードのエディタ上で new の場所を探したり、 あるいはブレークポイントをしかけたり print 文を追加しておけば、 どれだけのインスタンスが生成されたかは明確に分かります。 #リフレクションが絡むと違うのかな?細かなことは良くは分かりませんが。 提示されたコードだと Class_B の new が1箇所だけ、Class_C の new も1箇所だけであり、 Class_A の new がされている箇所がないので、 厳密に言えば Class_A のインスタンスはひとつもできません。 もちろん、ご説明で暗黙の内に Class_A のインスタンスを main メソッド内あたりで生成されているのだと思いますが、 もしそれが1回だけの new なら Class_A のインスタンスもひとつだけです。 Class_B や Class_C がフィールドとして持っている Class_A は、 そのひとつのインスタンスを共有しているだけです(分離されていない)。 老婆心ながらサンプルは、 上記のような main メソッド(?)内での new などについても 省かずに提示されるとサンプルが厳密になって良いと思います。 #今のものでも分かりやすい良いサンプルだと思いますが。 ただ、なにをもくろまれているのかが、サンプルからはイマイチ分からないです。 単に、Java におけるクラス間の関係をいろいろ試されているだけなのか、 なにか目的があってこういうことをする必要があるのかの、どちらでしょうか。 | ||||
|
投稿日時: 2003-11-19 10:32
unibon です。こんにちわ。
Java はインスタンスを生成するためには必ず new しないといけないので、 ソースコードのエディタ上で new の場所を探したり、 あるいはブレークポイントをしかけたり print 文を追加しておけば、 どれだけのインスタンスが生成されたかは明確に分かります。 #リフレクションが絡むと違うのかな?細かなことは良くは分かりませんが。 提示されたコードだと Class_B の new が1箇所だけ、Class_C の new も1箇所だけであり、 Class_A の new がされている箇所がないので、 厳密に言えば Class_A のインスタンスはひとつもできません。 もちろん、ご説明で暗黙の内に Class_A のインスタンスを main メソッド内あたりで生成されているのだと思いますが、 もしそれが1回だけの new なら Class_A のインスタンスもひとつだけです。 Class_B や Class_C がフィールドとして持っている Class_A は、 そのひとつのインスタンスを共有しているだけです(分離されていない)。 老婆心ながらサンプルは、 上記のような main メソッド(?)内での new などについても 省かずに提示されるとサンプルが厳密になって良いと思います。 #今のものでも分かりやすい良いサンプルだと思いますが。 ただ、なにをもくろまれているのかが、サンプルからはイマイチ分からないです。 単に、Java におけるクラス間の関係をいろいろ試されているだけなのか、 なにか目的があってこういうことをする必要があるのかの、どちらでしょうか。 | ||||
|
投稿日時: 2003-11-19 10:37
上記のコードだと、クラスAのオブジェクトは1つしかありません。ただし、クラスAのオブジェクトへの参照は3つあります。
オブジェクトがメモリ上に生成されるのは new Class_A() とした時です。Class_BやClass_C内では new Class_A() という記述がないのでオブジェクトは作られていません。ただし、既に作られているClass_Aのオブジェクトへの「参照」が渡されています。 ここら辺はJavaでは非常に大事です。 | ||||
|
投稿日時: 2003-11-19 10:48
Javaでは、メソッドの引数は参照渡し(プリミティブ型以外)になるので、上の例だとクラスAは1つだけになります。
参照は、C等のポインタとほぼ同じものと考えればいいと思います。 ポインタとの違いは、ポインタだと「ポインタのポインタ」が出来ますが、 「参照の参照」はできないことだったかな。(他にも違いはあると思いますが) 現実的に言うと、家(Object)を建てて友人には住所(参照)を教えるって感じで(変な例えだ)。 | ||||
|
投稿日時: 2003-11-19 10:59
unibonさん、H2さんご意見ありがとうございました。
>ただ、なにをもくろまれているのかが、サンプルからはイマイチ分からないです。 >単に、Java におけるクラス間の関係をいろいろ試されているだけなのか、 >なにか目的があってこういうことをする必要があるのかの、どちらでしょうか。 前者です、クラス間での関係やガベージコレクションを勉強しています。 >上記のコードだと、クラスAのオブジェクトは1つしかありません。 >ただし、クラスAのオブジェクトへの参照は3つあります。 なるほど、"new"してインスタンスしなければ新しくメモリー上に生成されないのですね。 ということは、例えばクラスBを下記のようにした場合("makeClassC() "メソッドに"clsC = null;"の一文を入れました。) クラスCの中でクラスAを参照している為、クラスBの中の"clsC"がGCによって解放されはしないと考えていいのでしょうか? public class Class_B { Class_A clsA;//クラスBの中でのクラスA public Class_B(Class_A cls) { clsA = cls; } void makeClassC(){ Class_C clsC = new Class_C(clsA); //クラスC作成 clsC = null; } } | ||||
|
投稿日時: 2003-11-19 11:16
> クラスCの中でクラスAを参照している為、クラスBの中の"clsC"がGCによって
> 解放されはしないと考えていいのでしょうか? 違います。逆です。clsCが参照していたClass_Cのオブジェクトは clsC=null; でGCによって開放されてしまいます。この時点でclsCが参照していたClass_Cのオブジェクトを参照している物が何もないからです。逆に、clsCが参照していたオブジェクトが開放された後でも、clsCが参照していたClass_AのオブジェクトはClass_Bのオブジェクトが参照しているのでまだメモリ上に残ります。 >現実的に言うと、家(Object)を建てて友人には住所(参照)を教えるって感じで(変な例えだ) 面白いですね [ メッセージ編集済み 編集者: H2 編集日時 2003-11-19 11:26 ] | ||||
