プロが教えるわが家の防犯対策術!

最近Javaの勉強を始めました。
入門書に従って進めているのですが、
例題に下記のようなプログラムが載っていました。
for文の中でインスタンスを作ってループさせているのですが、
下記のプログラムだと"fusen" "label"という同名のインスタンスが複数できることになると思います。
結果は複数の付箋がデスクトップに表示されるので参考書通りといえばそうなのですが、

同名のインスタンスが複数作成されてしまうというのは例えば同じ名前の変数が複数、しかも同じブロック内で作成されてしまうというのと同じような気がします。
後々3番目に作ったインスタンスのメソッドだけを使いたいとかと思った場合、
困るのではないかと思いますし、そもそも同じ名前のインスタンスを複数作れるというのは
有りなのでしょうか?
上手く説明できないのですが、何だか気持ち悪くてしょうがありません。
どなたかアドバイス頂けないでしょうか?

(注)
"Dodai"クラスは入門書付属の拡張ライブラリなのですが、
デスクトップに付箋を表示するためのクラスです。
"JLabel"クラスは"Java Platform Standard Edition 6"のものを使用しています。
-----------------------------------------------------------
public static void main(String[] args){
//外側の繰り返し
for( int i = 1; i <= 9; i++ ){
//内側の繰り返し
for( int k = 1; k <= 9; k++ ){
Dodai fusen = new Dodai();
JLabel label = new JLabel();
label.setText(i + "x" + k + "=" + ( i*k ));
fusen.add(label);
fusen.setSize(50, 30);
fusen.setLocation(i * 60, k * 40);
fusen.setVisible(true);
}
}
}

A 回答 (3件)

変数をインスタンスの「名前」というあたりに誤解があるように思います。



インスタンスには「リファレンス」といって、そのインスタンスがどこに置いてあるのかを示す、いわば「固有の番号」があります。newで新しいインスタンスが作られたら、新しい「番号」が付きます。
変数は、その「番号」を覚えているだけです。

リファレンスだけに注目すれば、こんなイメージです。

int Reference=1;
...
int fusen = Reference ++ ; // 実際に「次」になるとは限りませんが
int label = Reference ++ ; // 別の値になる、という意味では同等です。


> 後々3番目に作ったインスタンスのメソッドだけを使いたいとかと思った場合

そういう場合は、覚えておくようにプログラムを作ります。( Dodai fusen[][]→newで配列確保して、fusen[i][k]=new Dodai(); とか)
    • good
    • 0

名前が同じなので多少混乱するかもしれないですが、ループの中を一度出たものは破棄されて再度ループに入った時に作られるインスタンスは別になります。



分かり易く(かどうかは分かりませんが)いうと
一回目のループ
for(1){
fusen[1] ←一回目のインスタンス
}
二回目のループ
for(2){
fusen[2] ←一回目のインスタンス
}
こんな感じです。
実際に[1]とかにはなりませんが、イメージ的にそんな感じで捉えればいいと思います。
Cみたいな明示的なデストラクタはないので、ループの最後にデストラクタがあるみたいな捉え方でもいいかもしれません。
    • good
    • 0
この回答へのお礼

fusen,labelは消滅して生成されてを繰り返しているのですね。
デスクトップ上に付箋は表示されたままですが、forループが終わるとfusenのスコープは終わって変数は消滅しているのですね?
スコープの考え方が足りなかったのですね。
ありがとうございました。

デスクトップ上に付箋が残っているのは変数のスコープが終わっても
実行された内容はメモリ上に残っているからでしょうか?

どうでしょうか、認識は正しいでしょうか?

お礼日時:2011/09/03 02:14

まず「『変数』と『(その変数に代入した) インスタンス』とは別物である」という意識を持ってください. そして, 「変数は (直接囲む) ブロックが終わったときに消滅する」ことも認識してください. つまり, i=1, k=1 のときの変数fusen と i=1, k=2 のときの変数fusen とは「違う変数」です. プログラムの字面上同じ名前ですが, あくまで違う変数です.



で確かに「後々3番目に作ったインスタンスのメソッドだけを使いたいとかと思った場合、
困る」んだけど, それは (今の場合) あくまで「変数が消滅する (その結果当該インスタンスにアクセスする方法がなくなる)」ことによる影響でしかありません. そして, そういう必要性があるならこんなプログラムは書きません.

そもそも for の変数 k も同じ状況にあるんだけど, それは「気持ち悪い」とは思いませんでしたか?

この回答への補足

ありがとうございます。
kに関しては変数の中身が入れ替わっているという認識ですが、
付箋がデスクトップ上に複数表示されているので、fusenの中身は書き変わっていますよね。
fusenはオブジェクト型の変数なので、アドレスが入っているのだと思っているのですが、

あ、この文を書いていて気づいたのですが、一回目と二回目のfusenの中に入っているアドレスは違うモノが入っていて、forループの中の処理が実行される度にfusenの中に入るアドレスが書き換わっているのですね。

デスクトップ上に付箋は表示されたままですが、forループが終わるとfusenのスコープは終わって変数は消滅しているのですね?

どうでしょうか、認識は正しいでしょうか?

補足日時:2011/09/03 01:46
    • good
    • 0

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!