質問をすることでしか得られない、回答やアドバイスがある。

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

新規登録して質問してみよう
ただいま回答率
85.48%
Java

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

Q&A

解決済

2回答

13429閲覧

インスタンスの生成を配列で行うときの初期化子について

ramune3

総合スコア11

Java

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

0グッド

0クリップ

投稿2017/05/29 05:35

###質問内容
Javaを学んで約2か月です。
Mainメソッドから呼んだ、処理を行うクラスのフィールドで、配列を用いて別のクラスのインスタンスを生成したいです。
以下のソースコードで生成したところ、「メソッド名が無いのにどのように呼び出すのか」という指摘を受けました。
コンパイル、実行共にできています。

・初期化子にはその配列に格納したいデータを入れる
・int[] hoge = new int[]{10,20,30};もしくは、int[] hoge = {10,20,30}のような使い方が正しい使い方である

以上のように配列の記述方法を認識しています。
指摘を受けるまでは、”初期化子としてFor文を記述しているので、メソッド内で記述していなくても動作するのではないか”、と考えていました。
その後、検索をしたり、テキストを読み直してもこの書き方をしている物が見当たらないので、書き方が誤っているのだろう、というのは見当が付きました。

・なぜメソッドが無いのにこの書き方でエラーが起きないのか
・フィールドで配列を用いてインスタンス生成したいときの正しい記述方法
以上の2点について教えていただきたいです。
よろしくお願いします。
###該当のソースコード

Java

1public class Hoge{ 2//その他に変数を3つ定義中 3 HogeHoge[] hoge = new HogeHoge[10];{ 4 for(int i = 0; i <= 9; i++){ 5 hoge[i] = new HogeHoge(); 6 } 7 } //以下にメソッドが2つ 8}

###試したこと

Java

1HogeHoge[] hoge = new HogeHoge[10]{ 2 for(int i = 0; i <= 9; i++){ 3 hoge[i] = new HogeHoge(); 4 } 5 }

→エラー:';'がありません
その他、該当部分のどこかをいじるとFor文以降がコンパイルエラーになります。
この書き方以外ではエラーが起こるのになぜこれだけ問題なく動く…?と疑問が深まるばかりでした。

Java

1//インスタンス生成を行うためのメソッドを作成 2public static void main(String[] args){ 3 HogeHoge[] hoge = new HogeHoge[10];{ 4 for(int i = 0; i <= 9; i++){ 5 hoge[i] = new HogeHoge(); 6 } 7 } 8}

→同一クラス内のメソッドにhogeが存在しない旨のエラーが表示される(ほかのメソッドからスコープ範囲外になるのでエラーになると認識しています。)

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

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

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

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

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

guest

回答2

0

最初のコードは、以下のように解釈されます。

java

1public class Hoge{ 2 // ここで配列を宣言(nullで埋められる) 3 HogeHoge[] hoge = new HogeHoge[10]; 4 5 // 以下のブロックは「インスタンスイニシャライザ」として、 6 // インスタンス生成のたびに実行される 7 { 8 for(int i = 0; i <= 9; i++){ 9 hoge[i] = new HogeHoge(); 10 } 11 } //以下にメソッドが2つ 12}

ただ、一般に「インスタンスイニシャライザ」は積極的に活用するものではなく、コンストラクタ内に同等のコードを書くのが一般的です。

投稿2017/05/29 05:48

maisumakun

総合スコア145183

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

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

ramune3

2017/05/29 06:21 編集

回答ありがとうございます。 インスタンスイニシャライザを知らなかったので、検索してみて初期化ブロックと同義かと思ったのですが、この認識で正しいでしょうか? >コンストラクタ内に同等のコード HogeHoge[] hoge = new HogeHoge[10]; をHogeクラスで生成し、HogeHogeクラスのコンストラクタとして for文を記述するということでしょうか?
maisumakun

2017/05/29 06:22

配列のnewは宣言時点でやってしまえば、コンストラクタでもう一度行う必要はありません。 コンストラクタ内ではループを回してnew、の部分だけで大丈夫です。
ramune3

2017/05/29 06:59

```Java public class Hoge{ HogeHoge[] hoge = new HogeHoge[10]; } ``` ```Java public class HogeHoge{ HogeHoge(){ for(int i = 0; i <= 9; i++){ new HogeHoge(); } } ``` ということでしょうか。 new HogeHoge[10]; のnewの後って、配列の形をしてますが、HogeHoge()と同じでコンストラクタを呼び出す役割ということですか? 次々質問して申し訳ありません。
ramune3

2017/05/29 07:07

すみません、上の書き込みだとHogeの時点でnewをしているので、コンストラクタは不要ということですね。 もういちどじっくり考えてから再度質問します。
ramune3

2017/05/29 08:23 編集

public class Hoge{ HogeHoge[] hoge =new HogeHoge[10]; Hoge(){ for(int i = 0; i <= 9; i++){ hoge[i] = new HogeHoge(); } } 上記のように作成いたしました。 HogeのフィールドでHogeHoge配列を宣言し、Hogeが呼び出されたときに、Hogeのコンストラクタ内で配列の初期化を行う、ということですね! 丁寧な回答ありがとうございました。
guest

0

ベストアンサー

・なぜメソッドが無いのにこの書き方でエラーが起きないのか

Javaには初期化ブロックという仕様があります。偶然、初期化ブロックの記述方法になっているのでエラーにはなりません。

・フィールドで配列を用いてインスタンス生成したいときの正しい記述方法

インスタンス作成時に一度だけ初期化するならコンストラクタや初期化ブロックに書くといいですが、何度も初期化をするなら初期化処理をそのままメソッド化しておくべきですね。

投稿2017/05/29 05:48

編集2017/05/29 05:49
yona

総合スコア18155

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

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

ramune3

2017/05/29 06:20 編集

回答ありがとうございます。 >何度も初期化をするなら初期化処理をそのままメソッド化しておくべきですね。 この場合、インスタンスが生成された後にFor文で10回初期化処理が行われているということでしょうか?
yona

2017/05/29 06:22

行われません。 コンストラクタでメソッドを呼び出すか、インスタンス生成後にメソッドを呼ぶようにしないといけません。 これは仕様の問題なので回答はできません。
ramune3

2017/05/29 06:45

行われないのですね、動作のイメージが出来ました。 初期化ブロックの仕様について、もう少し調べてみます。 ありがとうございます。
yona

2017/05/29 06:48

maisumakunさんの回答にもあるように初期化ブロック、インスタンスイニシャライザを使うと無駄な混乱の元になるのでコンストラクタで書くべきですよ。
ramune3

2017/05/29 07:10

仕様を知って混乱するよりも、コンストラクタで記述できるようにした方がいいんですね。 コンストラクタで記述できるように考え直してみます。ありがとうございます。
yona

2017/05/29 07:24

初期化ブロックの仕様は理解すべきです。 問題なのはあなた以外の開発者です。 あなたは今回のことで初期化ブロックを理解すると思いますが、他の方ももしかしたらあなたと同じつまずきをする可能性があります。
ramune3

2017/05/29 07:29

他の方のことも考えて理解するべきなんですね。 わかりました。調べてみます。 ありがとうございます。
ramune3

2017/05/29 08:23

質問内容のプログラムに関して、 >コンストラクタでメソッドを呼び出す こちらのやり方で、初期化ブロックを使用せずに動作することができました! 初期化ブロック、インスタンスイニシャライザに関しては、引き続き正しく理解し、他の方が同じ躓きをしているときに対処できるよう勉強していきます。 丁寧な回答ありがとうございました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

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

ただいまの回答率
85.48%

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

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

質問する

関連した質問