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

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

ただいまの
回答率

90.36%

  • Java

    15092questions

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

配列のnewの有無について

解決済

回答 4

投稿

  • 評価
  • クリップ 0
  • VIEW 180

nainai

score 3

int[] a = new int[] {1, 2, 3};

int[] a = {1, 2, 3};

この2つの表記方法は同じ役割を果たしていると言えるのでしょうか?

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

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

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

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

回答 4

checkベストアンサー

+5

同じ役割を果たしていると言えるのでしょうか?

後者は
・ローカル変数やフィールドの宣言と同時に与える「初期値」としてのみ許される

前者は
・ローカル変数やフィールドへの再代入の右辺やメソッドへの実引数などにも使える「一般的な式」

というところが役割として違う点です。つまり使える場面の違いです。後者がメソッドの実引数にも使えると便利な気もしますが・・・

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

class A {
  void foo() {
    // (A)
    int[] a = { 10, 20 };

    // (B)
    a = new int[] { 10, 20 };

    // (C)
    a = new int[2];
    a[0] = 10;
    a[1] = 20;
  }
}


コンパイルしてbyte codeを見てみますと・・・

$ javac A.java
$ javap -v A.class
...
    Code:
      stack=4, locals=2, args_size=1
         # ----- (A) ----- int[] a = { 10, 20 };
         0: iconst_2
         1: newarray      int  # 要素数2の配列を生成
         3: dup                # 配列をスタック上にコピー
         4: iconst_0           # 0をスタックに積む
         5: bipush        10   # 10をスタックに積む
         7: iastore            # stack[2](=配列)のstack[1](=0)番目にstack[0](=10)を格納
         8: dup                # 以下同様
         9: iconst_1
        10: bipush        20
        12: iastore
        13: astore_1           # 配列をローカル変数aに代入
        # ----- (B) ----- a = new int[] { 10, 20 };
        14: iconst_2           # (A)と全く同じ
        15: newarray      int
        17: dup
        18: iconst_0
        19: bipush        10
        21: iastore
        22: dup
        23: iconst_1
        24: bipush        20
        26: iastore
        27: astore_1
        # ----- (C) -----
        28: iconst_2
        29: newarray      int  # 要素数2の配列を生成
        31: astore_1           # 配列をローカル変数aに代入(これが(A),(B)と意味的に違う)
        32: aload_1            # あとは若干byte codeが違うが意味的に(A),(B)と同じ
        33: iconst_0
        34: bipush        10
        36: iastore
        37: aload_1
        38: iconst_1
        39: bipush        20
        41: iastore
...

(A)(B)は全く同じbyte codeになっており「配列の全体の要素値が確定してから変数へ代入される」のに対して、(C)は「まず全要素が要素型によって決まる値(intなら0)の配列が変数へ代入されてから各要素が初期化される」のがわかります((C)はそう書いているので当たり前ですが...)。

投稿

編集

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/02/12 17:31

    理解できました、回答ありがとうございます。

    キャンセル

+2

同じです。ただし、newがない方は変数宣言と同時にしか使えません。

int[] a = {1, 2, 3};
// a = {4, 5, 6};  // コンパイルエラー
a = new int[]{4, 5, 6};

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2019/02/12 17:32

    わかりやすかったです、ありがとうございます。

    キャンセル

+1

同じバイトコードが生成されていましたので, 同じ役割を果たしていると言えると思います.

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

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/12 17:32

    回答ありがとうございます。

    キャンセル

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

  • ただいまの回答率 90.36%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

同じタグがついた質問を見る

  • Java

    15092questions

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