int[] a = new int[] {1, 2, 3};
と
int[] a = {1, 2, 3};
この2つの表記方法は同じ役割を果たしていると言えるのでしょうか?
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
回答4件
0
ベストアンサー
同じ役割を果たしていると言えるのでしょうか?
後者は
・ローカル変数やフィールドの宣言と同時に与える「初期値」としてのみ許される
前者は
・ローカル変数やフィールドへの再代入の右辺やメソッドへの実引数などにも使える「一般的な式」
というところが役割として違う点です。つまり使える場面の違いです。後者がメソッドの実引数にも使えると便利な気もしますが・・・
void foo(int[] a)
(M1)
void foo(Object[] a)
(M2)
のどちらに適合するかfoo({1, 2, 3})
のような型なしの表現だと曖昧さが残ります。一方new int[] {...}
というように「要素の型が明確な式」ならM1のメソッドの引数であることがはっきりしますね。変数の宣言と同時にしか使わない初期値ならば「変数の型は自明」なので前述のような曖昧さが起きません。そういうわけで「初期値」だけはnew int[]
が省略できる簡便な構文を許しているのではないでしょうか?
実際の動作の結果についていえば、下のコードの(A)(B)は全く同じbyte codeにコンパイルされるようです。さらにいえば若干の意味的な違いを除けば(C)とほぼ同じ意味になります。
A.java
java
1class A { 2 void foo() { 3 // (A) 4 int[] a = { 10, 20 }; 5 6 // (B) 7 a = new int[] { 10, 20 }; 8 9 // (C) 10 a = new int[2]; 11 a[0] = 10; 12 a[1] = 20; 13 } 14}
コンパイルしてbyte codeを見てみますと・・・
bash
1$ javac A.java 2$ javap -v A.class 3... 4 Code: 5 stack=4, locals=2, args_size=1 6 # ----- (A) ----- int[] a = { 10, 20 }; 7 0: iconst_2 8 1: newarray int # 要素数2の配列を生成 9 3: dup # 配列をスタック上にコピー 10 4: iconst_0 # 0をスタックに積む 11 5: bipush 10 # 10をスタックに積む 12 7: iastore # stack[2](=配列)のstack[1](=0)番目にstack[0](=10)を格納 13 8: dup # 以下同様 14 9: iconst_1 15 10: bipush 20 16 12: iastore 17 13: astore_1 # 配列をローカル変数aに代入 18 # ----- (B) ----- a = new int[] { 10, 20 }; 19 14: iconst_2 # (A)と全く同じ 20 15: newarray int 21 17: dup 22 18: iconst_0 23 19: bipush 10 24 21: iastore 25 22: dup 26 23: iconst_1 27 24: bipush 20 28 26: iastore 29 27: astore_1 30 # ----- (C) ----- 31 28: iconst_2 32 29: newarray int # 要素数2の配列を生成 33 31: astore_1 # 配列をローカル変数aに代入(これが(A),(B)と意味的に違う) 34 32: aload_1 # あとは若干byte codeが違うが意味的に(A),(B)と同じ 35 33: iconst_0 36 34: bipush 10 37 36: iastore 38 37: aload_1 39 38: iconst_1 40 39: bipush 20 41 41: iastore 42...
(A)(B)は全く同じbyte codeになっており「配列の全体の要素値が確定してから変数へ代入される」のに対して、(C)は「まず全要素が要素型によって決まる値(intなら0)の配列が変数へ代入されてから各要素が初期化される」のがわかります((C)はそう書いているので当たり前ですが...)。
投稿2019/02/11 18:49
編集2019/02/12 02:33総合スコア18394
0
Javaでnew int[] {1, 2, 3};
とすると、配列の実体はヒープ領域に作成されます。
C言語の場合、ヒープ領域に配列の実体を作ろうとすると、int *a = (int *) malloc(sizeof(int) * 3);
とします。
ヒープ領域でメモリを確保する手段として、Javaの場合はnew
を、Cの場合はmalloc
を使う感じです。
話は変わって、C言語の場合、int a[] = {1, 2, 3};
すると、配列はスタック領域に確保されます。
それに対して、Javaの場合、int a[] = {1, 2, 3};
の場合でも配列の実体はヒープ領域に作成されます。
結果として、Javaの場合、どちらも変わらないということだと思います。
投稿2019/02/11 18:18
総合スコア207
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2019/02/12 08:31