インスタンスを同じ名前で作成することはできる?

このQ&Aのポイント
  • Javaの勉強を始めていますが、for文の中で同じ名前のインスタンスを作成することについて疑問があります。
  • 同じ名前のインスタンスが複数作成されると、後々特定のインスタンスのメソッドを使う際に困ることがあるのではないかと思います。
  • 誰かアドバイスいただけませんか?
回答を見る
  • ベストアンサー

インスタンスを同じ名前で作成できる?

最近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); } } }

  • Java
  • 回答数3
  • ありがとう数4

質問者が選んだベストアンサー

  • ベストアンサー
  • kmee
  • ベストアンサー率55% (1857/3366)
回答No.3

変数をインスタンスの「名前」というあたりに誤解があるように思います。 インスタンスには「リファレンス」といって、そのインスタンスがどこに置いてあるのかを示す、いわば「固有の番号」があります。newで新しいインスタンスが作られたら、新しい「番号」が付きます。 変数は、その「番号」を覚えているだけです。 リファレンスだけに注目すれば、こんなイメージです。 int Reference=1; ... int fusen = Reference ++ ; // 実際に「次」になるとは限りませんが int label = Reference ++ ; // 別の値になる、という意味では同等です。 > 後々3番目に作ったインスタンスのメソッドだけを使いたいとかと思った場合 そういう場合は、覚えておくようにプログラムを作ります。( Dodai fusen[][]→newで配列確保して、fusen[i][k]=new Dodai(); とか)

その他の回答 (2)

回答No.2

名前が同じなので多少混乱するかもしれないですが、ループの中を一度出たものは破棄されて再度ループに入った時に作られるインスタンスは別になります。 分かり易く(かどうかは分かりませんが)いうと 一回目のループ for(1){ fusen[1] ←一回目のインスタンス } 二回目のループ for(2){ fusen[2] ←一回目のインスタンス } こんな感じです。 実際に[1]とかにはなりませんが、イメージ的にそんな感じで捉えればいいと思います。 Cみたいな明示的なデストラクタはないので、ループの最後にデストラクタがあるみたいな捉え方でもいいかもしれません。

unmarko
質問者

お礼

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

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.1

まず「『変数』と『(その変数に代入した) インスタンス』とは別物である」という意識を持ってください. そして, 「変数は (直接囲む) ブロックが終わったときに消滅する」ことも認識してください. つまり, i=1, k=1 のときの変数fusen と i=1, k=2 のときの変数fusen とは「違う変数」です. プログラムの字面上同じ名前ですが, あくまで違う変数です. で確かに「後々3番目に作ったインスタンスのメソッドだけを使いたいとかと思った場合、 困る」んだけど, それは (今の場合) あくまで「変数が消滅する (その結果当該インスタンスにアクセスする方法がなくなる)」ことによる影響でしかありません. そして, そういう必要性があるならこんなプログラムは書きません. そもそも for の変数 k も同じ状況にあるんだけど, それは「気持ち悪い」とは思いませんでしたか?

unmarko
質問者

補足

ありがとうございます。 kに関しては変数の中身が入れ替わっているという認識ですが、 付箋がデスクトップ上に複数表示されているので、fusenの中身は書き変わっていますよね。 fusenはオブジェクト型の変数なので、アドレスが入っているのだと思っているのですが、 あ、この文を書いていて気づいたのですが、一回目と二回目のfusenの中に入っているアドレスは違うモノが入っていて、forループの中の処理が実行される度にfusenの中に入るアドレスが書き換わっているのですね。 デスクトップ上に付箋は表示されたままですが、forループが終わるとfusenのスコープは終わって変数は消滅しているのですね? どうでしょうか、認識は正しいでしょうか?

関連するQ&A

  • インスタンスの作成について

    下記の方法にてHashtableのインスタンスを作成しようと思ったのですが has1.put("key",1); の場所でNullpointerException が発生します。 has1がNullになってしまうのですが 下記のような手法でインスタンスは作れないのでしょうか。 public class InstanceCreate { Hashtable has1; Hashtable has2; Hashtable has3; public static void main(String[] args) { InstanceCreate instance = new InstanceCreate(); instance.exe(); } public void exe() { Hashtable hash[] = {has1,has2,has3}; for(int i=0; i<hash.length;i++){ hash[i] = new Hashtable(); hash[i].put("key", "value"); } has1.put("key",1); } }

    • ベストアンサー
    • Java
  • Dimensionクラスの使い方

    Javaを始めたばかりの者です。 参考書を読みながら進めていて下記のソースコードで Dimensionクラスを使用している箇所で行き詰まりました。 使われていたのは、以下のコード --------------------------------------------------------------------------------------------------------------------- import java.awt.*; import javax.swing.*; import java.util.*; class xxx{  static public void main(String[] argv){  /*標準入力からmsgに文字列を入力*/  String msg = scan.next();  /*JLabelクラス型のオブジェクト型変数を作成し、インスタンスを生成*/  JLabel label = new JLabel(msg);  /*JLabelのインスタンスのコンストラクタに入力されたmsgのサイズを取得*/  Dimension dim = label.getPreferredSize();  ・・・etc  } } ---------------------------------------------------------------------------------------------------------------------- 自分が今まで使ってきたクラスは下記のような感じで使っていましたが、ここではnewしていない。 これは、どういうことなんでしょうか? クラス名 dim = new クラス名(); インスタンス作成 = コンストラクタの呼び出し。 new演算子はクラスのコンストラクタを呼び出している理解ですが Dimension dim = label.getPreferredSize(); 上記のコードではDimentionクラスのインスタンスは作られていないということだと思います。 ということは、 ここでは何をしているのでしょうか? どなたか、教えて下さい。

    • ベストアンサー
    • Java
  • クラスのインスタンス

    お世話になります クラスのインスタンスを生成する際に class CTest { int m_i; } CTest* pTest = new CTest; void main() { pTest->m_i = 0; } CTest::~CTest() { delete pTest; } と、関数外でインスタンス化する際にも、newを使用するのでしょうか? もう1つ、newを使用しないで CTest Test; CTest* pTest = &Test; とするのと、何が違うのでしょうか? 多分、根本的な所が理解できていないと思われますが、よろしくお願い致します

  • (C++) for文内でのインスタンス生成について

    はじめまして。 いつも色々と質問を読まさせて頂いています。 早速タイトルの質問についてですが、for文の中でループさせながらインスタンスを生成しようとしています。 for (int i=0; i<10; i++) { MyObject *obj = new MyObject(); int intX = new int(100); // メモリのアドレスを確認 printf("%p¥n", &obj); printf("%p¥n", &intX); } この結果、 0xbfffd7dc 0xbfffd7f0 0xbfffd7dc 0xbfffd7f0 0xbfffd7dc 0xbfffd7f0 0xbfffd7dc 0xbfffd7f0 . . のようになり、どうも同じメモリアドレスを参照したインスタンスが生成されているようです。 やりたい事は、10回のインスタンスの生成をforで手抜きして行いたいのですが、この方法ですとすべて同じインスタンスとなってしまい、 別の処理でとある一つのインスタンスに変更を加えると、すべてのインスタンスにも変更がかかってしまいます。 これを実現する方法はあるのでしょうか。 解決方法として、forを使わずに、 MyObject *obj1 = new MyObject(); MyObject *obj2 = new MyObject(); . . とやれば別アドレスの参照となることは分かったのですが。。。 初歩的な質問だと思いますが、お知恵をお借りできればと思います。 よろしくお願いします。

  • クラスとインスタンスについて

    はじめまして。Javaをはじめて3か月の超初心者です。 早速ではございますが、質問をさせていただきます。 以下のサンプルで、 class Foo { private int i = 0; Foo(int i) { this.i = i; } void func1() { System.out.println(this.i); } void func2(Foo foo) { System.out.println(foo.i); } } class Main { public static void main(String[] args) { Foo obj1 = new Foo(100); Foo obj2 = new Foo(500); obj1.func1(); obj1.func2(obj2); } } privateフィールドのスコープは同一クラス内からしか アクセスできないと参考書には記述されているの ですが、そのクラス内に上のサンプルのように this.iやfoo.iというように、クラスは同じでも インスタンスが異なるものがiにアクセスするとき、 上のサンプルは、どちらもアクセス制限のエラーが表 示されません。なぜなのでしょうか? this.iというアクセスは、現在実行中のインスタン ス内でのアクセスなので、privateスコープ内での アクセスであるというような感じがするのですが、 foo.iというアクセスの方は、現在実行中のインスタンスとは異なるインスタンス内でのアクセスなので、 privateスコープからはずれているような感じがして なりません。

    • ベストアンサー
    • Java
  • ステージにある複数のインスタンスを制御したいです

    ステージに配置してある複数のインスタンスをアクションスクリプトで制御したいです。 インスタンスには「mc0」~「mc9」の連番で名前をつけています。 例えば、それぞれのインスタンスのタイムラインを再生させる指示を与えるとすると、 mc0.gotoAndPlay("main"); mc1.gotoAndPlay("main"); mc2.gotoAndPlay("main"); mc3.gotoAndPlay("main"); ・ ・ ・ mc9.gotoAndPlay("main"); となると思いますが、もっとスマートに書くとするとどんな書き方があるでしょうか? 数がもっと増える可能性があるので、もっと合理的な方法を知りたいです。 アクションスクリプトで生成したインスタンスを動かすには、 for(var i:int=0;i<10;i++){ var mc:MovieClip=new McMC(); addChild(mc); mc.name="mc"+i; mc.x=200+i*50; mc.y=200; mc.gotoAndPlay("main"); } のような感じで動かすのはやったことがあるので 既にステージに直接配置されているインスタンスもfor文で同じように制御できると思い 以下のように試してみましたが… for(var i:int=0;i<10;i++){ var mc:MovieClip; mc.name="mc"+i; mc.x=200+i*50; mc.y=200; mc.gotoAndPlay("main"); } 未定義となってしまいます。 やはり地道に書くしかないのでしょうか? ご教授を宜しくお願い致します。 ※FlashCS4、AS3で作業しています。

    • ベストアンサー
    • Flash
  • panel.add(new Button("1"));という書き方について。

    javaを学習している者です。 インスタンスを作成するには クラス名 変数名 = new クラス名(); というのが基本だと思うのですが、タイトルのような書き方(panel.add(new Button("1"))だと頭の中ではどのように考えればいいのでしょうか?変数名を持たないインスタンスを生成してパネルにのっけている、ということでしょうか?しかもこれがfor文で繰り返されていると for(int i = 0; i < 10; i++){ panel.add(new Button(Integer.toString(i))); } 余計にややこしくて分からなくなってしまいます。一応10個違うインスタンスをそれぞれ作っているのでしょうか? 本に載っていた書き方だし、エラーも出ないのでまず間違っていないのは分かるのですが、いまいちピンと来ないです・・・。 よろしくお願いします。

    • ベストアンサー
    • Java
  • インスタンス生成について

    いつもお世話になっております。 今回はインスタンス生成について質問させて下さい。 String クラスのインスタンス生成は、 String str1 = new String(); のように明示的に new 演算子を用いる方法と、 String str2 = "hoge"; のように生成する方法がありますよね。 str2 の方は、JVM が(?) 勝手にコンストラクタを呼び出してくれて、 インスタンスを生成してくれる、という認識でよいのでしょうか? また、明示的に「 new 演算子 + コンストラクタ」でインスタンスを生成する場合と、 そうでない場合の使い分けなどはあるのでしょうか? そもそも String 以外に、このような複数のパターンでインスタンスを生成することができる クラスは他にもあるのでしょうか? 以上、ご教授宜しくお願い致します。

    • ベストアンサー
    • Java
  • スクロール表示

    お願いします。 初めてswingに挑戦中なのですが・・・ tableをスクロール表示させたいのですがどうしてもできません。どうしたらよいでしょうか?教えてください import java.lang.*; import javax.swing.*; import javax.swing.table.*; import java.awt.*; public class SwingTableApp extends JFrame { public JTable table; public JLabel label; public SwingTableApp(String[][] data) { super("parallel Machine Scheduling"); setLocation(50,50); setSize(400,700); setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); getContentPane().setLayout(null); DefaultTableModel tableModel = new DefaultTableModel(); for(int k=0; k<data[0].length; k++){ tableModel.addColumn("TEST"); }//列の設定 for(int j=0; j<data.length; j++){ tableModel.addRow(data[j]); }//行の設定 table = new JTable(tableModel); table.setLocation(10,10); table.setSize(2000,200); getContentPane().add(table); label = new JLabel("目的関数"); label.setLocation(10,210); label.setSize(100,25); getContentPane().add(label); } }

    • ベストアンサー
    • Java
  • 子インスタンスを登録するメソッドの作成

    Java初心者です。 学習中に躓いてしまったので、ご教示いただければと思います。 Testという1つのクラスを作成し、 そこから複数のインスタンスを作成します。 Test test1 = new Test(); Test test2 = new Test(); Test test3 = new Test(); 元のTestクラスの中に、 public void addSub(Test child) という、引数に指定したインスタンスを子に登録するメソッドを用意します。 実際に使うときは、 test1.addSub(test2); とすれば、test1の子にtest2が登録されるようにしたいのです。 基本的にサブクラスにするには、クラスを作る段階でextendsを用いるイメージなので、同じクラスの別インスタンスを親子関係にする、というのがよく分かりません。 このプログラムの目的は、最終的に一番親となったインスタンス(test1)の合計メソッドを呼び出して、自分の子供に登録されているインスタンス(test2,test3)全ての値を合算するということです。 質問の方法が曖昧で分かりにくいと思いますが、 指示いただければ追記いたしますので、 お時間のある方お力を貸していただければと思います。 宜しくお願いします。

    • ベストアンサー
    • Java

専門家に質問してみよう