🎄teratailクリスマスプレゼントキャンペーン2024🎄』開催中!

\teratail特別グッズやAmazonギフトカード最大2,000円分が当たる!/

詳細はこちら
Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

Q&A

解決済

1回答

562閲覧

java コンストラクタの初期化イメージと初期化ルール

KttShK

総合スコア9

Java

Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

0グッド

0クリップ

投稿2019/09/21 15:53

Javaを勉強し始めたばかりの初心者です。
コンストラクタの初期化イメージを教えてください。

発生している問題・エラーメッセージ

以下のような形で「test[i] = new testC();」をせずにRunしたところ、NullPointerExceptionが発生。
ネットで調べてNullを初期化する必要があるということで入れましたが、これを入れた後、このStringやIntが入り混じった
test[]がコンストラクタでどうやって初期化されていくかイメージがわきません。
(そもそも一行目の「testC[] test= new testC[3]」で初期化されているイメージでした。)

また一方でこういった初期化をせずに「testC[] test= new testC[3]」
だけで直接値を入れても問題ないこともありましました。

問題が見えておらず、別なところで初期化ができていただけなのかもしれませんが、
この部分のアドバイスをいただければ幸いです。

testC[] test= new testC[3];
for (int i = 0; i < 3; i++) {
test[i] = new testC(); // --> コンストラクタで初期化 → 初期化のイメージがわきません。
}
for (int i = 0; i < 3; i++) {
test[i].Name = test[i4];                        //String でtest[i]へ格納
test[i].qty = Integer.parseInt(test[(i
4)+1].trim());        //Int でtest[i]へ格納
test[i].unit = test[(i4)+2];                     //String でtest[i]へ格納
test[i].unitPrice = Float.parseFloat(test[(i
4)+3].trim());    //Float でtest[i]へ格納
}

public class testC {
String Name;
int qty;
String unit;
float unitPrice;

testC(){ } testC (String Name , int qty , String unit , float unitPrice) { this.Name = Name; this.qty = qty; this.unitPrice = unitPrice; this.unit = unit; }

}

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

最初に

  • オブジェクトの配列のインスタンス化をするときはObject[] array = new Object[3];
  • オブジェクト単体のインスタンス化をするときはObject element = new Object();

と書きます。

掲示しているコードで言うならば
testC[] test= new testC[3];が前者で
test[i] = new testC();が後者です。

回答

test[i]というのは配列全体を指している訳ではなくtestという配列の中の1つの要素を指しています。
ですから、test[0]test[1]test[2]も全て1つのオブジェクトを保持するだけの入れ物にしか過ぎません。

書き方を変えてみましょう。
下記のコードでも同様の動作をすると思います。

java

1testC[] test= new testC[3]; 2for (int i = 0; i < 3; i++) { 3 testC t = new testC(); //オブジェクトをインスタンス化をして 4 test[i] = t; //そのオブジェクトを配列の1要素に保持 5}

おそらく、「配列」と「配列の要素」を混同されているのではないでしょうか。

投稿2019/09/21 16:04

編集2019/09/21 16:24
BluOxy

総合スコア2663

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

KttShK

2019/09/21 16:30

早期回答本当にたすかります。ありがとうございます。ご説明いただいた部分はよく理解でいました。おっしゃる通り動きました。 確かにまだ混同しているかもしれません。。 不勉強で恐縮ですが教えて下さい。 Loopの中にインスタンス化を入れているのはLoopの中で都度インスタンス化することで初期化をしていくイメージなのでしょうか? 当初、配列をtestC[] test= new testC[3]; で定義・初期化➡ ここに値をいれていけば動くであろうという浅はかな思いでした。
BluOxy

2019/09/21 16:34

名前がややこしいので変数名testはarrayに置き換えます。 testC[] array = new testC[3]; は要素が3つ入るtestCの配列をインスタンス化しarrayに保持しています。 >Loopの中にインスタンス化を入れているのはLoopの中で都度インスタンス化することで初期化をしていくイメージなのでしょうか? そうです。掲示されたコードではfor上でその都度、配列の各要素をインスタンス化することで、arrayの各要素にそれぞれのインスタンスが保持されている状態になっています。
KttShK

2019/09/21 16:42

なるほど、ありがとうございます。一方でこういったインスタンス化をしなくても稼働するものもあるのですが、違いは何かあるのでしょうか? 前パターンとの違いはコンストラクタは使っていません。が、testC[] array = new testC[3]のように配列定義をして、直接値を入れていっています。これはClassの中でインスタンス化がきちんとなされているからということでしょうか?
BluOxy

2019/09/21 16:47 編集

Javaの型には「プリミティブ型」と「参照型」があります。 プリミティブ型はbooleanやint、float、charなどが該当し、参照型はクラスが該当します。 前者はインスタンス化は不要で、後者は必要です。 詳しくは色々な場所で解説もされているので「Java プリミティブ型 参照型」などと調べてみると良いでしょう。
BluOxy

2019/09/21 17:01 編集

> testC[] array = new testC[3]のように配列定義をして、直接値を入れていっています。 配列についてはインスタンス化をする際に[]を使って書く必要があります。 配列のインスタンス化にはコンストラクタに渡す引数は用意されていないので、()は省略してObject[] array = new Object[3];と書きます。
KttShK

2019/09/21 17:21

>配列のインスタンス化にはコンストラクタに渡す引数は用意されていないので、()は省略してObject[] array = new Object[3];と書きます。 今回は上記のインスタンス化に加えてコンストラクタを使って値初期化を行うために以下を入れたのですね。 for (int i = 0; i < 3; i++) { testC t = new testC(); //オブジェクトをインスタンス化をして test[i] = t; //そのオブジェクトを配列の1要素に保持 }
BluOxy

2019/09/21 17:23

そうです。配列と配列の要素という両方のインスタンス化を今回はやりたかったのでしょう。
KttShK

2019/09/21 18:43

よくわかりました。 ありがとうございました
KttShK

2019/09/23 05:02

ひとつ追加で教えてください。このtestC t = new testC();をループから外出しするとどういう動きになるのですか? 値が変になってしまったので気になっています。
BluOxy

2019/09/23 17:19 編集

今回の質問は「「testC[] test= new testC[3]」だけで直接値を入れても問題ない」かどうかが主旨という認識です。次から主旨に直接関連しない新たな疑問が沸いた際は別途質問を立ててください。 ※私の認識が違う場合は質問を編集して主旨が分かるよう書いてください。 というのを踏まえて「testC t = new testC();をループから外出しすると」どうなるかをお答えすると、testという配列の各要素に同じ物を指すインスタンス(t)が格納されます。よってtest[0].Nameを変えればtest[0]、test[1]、test[2]全てのNameが変えた値になります。 詳しくは「Java 参照型」「Java 参照型変数」などと調べてください。
KttShK

2019/09/25 12:31

どうもありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.36%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問