大変お世話になっております。
反逆する武士
uematu tubasaです。
初回投稿日時:2023年6月11日(令和5年6月11日)
本日もJavaの勉強をしていきましょう。
要素を1つも持たない配列
配列は値の集合を扱うための「インスタンス」です。
また、配列にはプリミティブ型とオブジェクト型の2種類がある。
要素で値そのものを扱うのか、参照(リンク情報)を扱うのかだけの違いがある。
int[] array = new int[0];
System.out.println(array);
実行結果:コンソールにハッシュコードが表示される。
上記のソースコードは「要素を1つも扱わないint型配列インスタンス」を生成しています。
その後、コンソールにハッシュコードが表示されることになります。
配列の宣言について
int[] a;
int b[];
int[][] c;
int d[][];
int[] e[];
int[][] f[];
実行結果:上記はどれもコンパイルエラーにならない。
1行目と2行目はint型配列となる。
3行目と4行目はint型の2次元配列となる。
5行目と6行目はint型の3次元配列となる。
型と変数、どちらに大カッコ([])を付与しても問題はない。
int[3] a;
int b[2];
int[2] c[];
int d[3][];
実行結果:上記4行にてコンパイルエラーになる。
配列型変数には、配列インスタンスへの参照を代入するだけで、参照先の配列がいくつの要素を扱えるかは関係ありません。
したがって、配列型変数を宣言するときには要素数を宣言することはできません。
int a[] = new int[2][3];
int[] b = new int[2.3];
int[] c = new int[];
int d[][] = new int[][3];
実行結果:上記4行にてコンパイルエラーになる。
1行目は1次元配列に対して、2次元配列を生成しているため、次元数が一致せず、コンパイルエラーになる。
2行目は配列インスタンスを生成する場合、要素数を整数で表す必要があるのに、浮動小数点数で表しているからコンパイルエラーになる。
3行目は配列インスタンスを生成する場合、要素数をそもそも記述していないため、コンパイルエラーになる。
4行目は1次元目の要素数は省略できないために、コンパイルエラーになる。
int [] a = new int[2]{2,3};
int b[][] = {};
int [][] c = new int[][]{};
int[] d;
d = new int[]{4,5};
int e[];
e = {6,7};
実行結果:1行目と7行目はコンパイルエラー。
1行目に関しては、初期化子({})が出てきたときには要素数は自動計算されるため、要素数を宣言しているとコンパイルエラーになる。
7行目に関しては、new int が記述されていないために、コンパイルエラーになる。
なぜならば、初期化子({})は変数宣言と同時にしか使用できないというルールが存在するから。
仮に、7行目をe = new int[]{7,8,9};と変更すると、コンパイルエラーは解消される。
配列のクローン問題
int[][] arrayA = { {1,2} , {1,2} , {1,2,3} };
int[][] arrayB= arrayA.clone();
int total = 0;
for(int[] tmp : arrayB){
for(int val : tmp){
total += val;
}
}
System.out.println(total);
実行結果:コンソールに12が出力される。
配列のクローンは参照先は異なるが全く同じ配列内容をコピーする。
したがって、if(arrayA == arrayB)と記述すると確実にfalseになる。
空の配列にて例外が発生する問題
Item[] items = new Item[3];
int total = 0;
for(int i = 0; i < items.length; i++){
total += items[i].price;
}
System.out.println(total);
実行結果:4行目で実行時エラー(NullPointerException)
1行目で「3つのItem型の配列インスタンス」を生成しています。
配列インスタンスを生成しているだけであり、Itemのインスタンスを生成しているわけではない。
要するに、実体が存在しない。
したがって、配列インスタンスの個数は問題無く得られる。
しかしながら、参照先が存在していないので例外(NullPointerException)が発生する。
以上です。