角括弧で囲まれたリストを使用しているときに、配列オブジェクト

new キーワードでコンストラクタを呼び出すと、 Javaarray

int[] myIntArray = new int[3];

しかし、もし私が代わりに

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

array オブジェクトが作成されますが、私は new でコンストラクタを呼び出していません。これはどのようにして動作しますか?コンストラクタを呼び出さずにJavaでオブジェクトを作成するにはどうすればいいですか?

3

6 答え

配列オブジェクトの作成に関する限り、それは構文的な砂糖です。コンパイルすると、標準構文とまったく同じように動作します。

ただし、最初のバージョンでは、配列に値を設定していません。すべての要素は、 int のデフォルト値です。これはゼロです。

2番目のバージョンでは、配列の作成、を行います。

6
追加された

最初のバージョンは整数配列にデフォルトの 0 値を設定します。 2番目の値は明示的に値を割り当てます。

最初のバージョンは

int[] myIntArray = {0, 0, 0};

2番目は同じです

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

新しいキーワードは、例えば、宣言的でないステートメントに対してのみ必須です。

int[] myIntArray;
myIntArray = new int[] {1,2,3};
4
追加された

このコードを手に入れてコンパイルしてください:

public class ArrayTest {
    public static void main1() {
        int[] array = new int[3]; array[0] = 10; array[1] = 20; array[3] = 30;
    }

    public static void main2() {
        int[] array = new int[] {10, 20, 30};
    }

    public static void main3() {
        int[] array = {10, 20, 30};
    }
}

次に、 javap -c を使用して逆アセンブルしてバイトコードを表示し、次の結果を得ます。しかし、あなたがすることは、後の2つのスニペットやメソッドが同じバイトコードにコンパイルされることです。したがって、 int [] array = new int [] {1,2,3}int [] array = {1、2、3} は同じです。しかし、配列を別々に作成し、その要素のそれぞれに値を割り当てることは異なって扱われるので、後の2つのスニペットは最初のスニペットの構文的な砂糖ではありません。

$ javap -c ArrayTest
Compiled from "ArrayTest.java"
public class ArrayTest extends java.lang.Object{
public ArrayTest();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."":()V
   4:   return

public static void main1();
  Code:
   0:   iconst_3
   1:   newarray int
   3:   astore_0
   4:   aload_0
   5:   iconst_0
   6:   bipush  10
   8:   iastore
   9:   aload_0
   10:  iconst_1
   11:  bipush  20
   13:  iastore
   14:  aload_0
   15:  iconst_3
   16:  bipush  30
   18:  iastore
   19:  return

public static void main2();
  Code:
   0:   iconst_3
   1:   newarray int
   3:   dup
   4:   iconst_0
   5:   bipush  10
   7:   iastore
   8:   dup
   9:   iconst_1
   10:  bipush  20
   12:  iastore
   13:  dup
   14:  iconst_2
   15:  bipush  30
   17:  iastore
   18:  astore_0
   19:  return

public static void main3();
  Code:
   0:   iconst_3
   1:   newarray int
   3:   dup
   4:   iconst_0
   5:   bipush  10
   7:   iastore
   8:   dup
   9:   iconst_1
   10:  bipush  20
   12:  iastore
   13:  dup
   14:  iconst_2
   15:  bipush  30
   17:  iastore
   18:  astore_0
   19:  return
2
追加された

両方のステートメントは同じです。 2番目のステートメントint [] myIntArray = {1,2,3};新しい方法を使用した構文の短縮です。

int [] myIntArray = {1,2,3}、配列のこの場合の長さは、中かっこで区切られ、コンマで区切られた値の数によって決まります。

2
追加された

フードの下では、配列を初期化する両方の方法が同じです。

別の例として、これを見てください:

String str = "Hello";//no 'new' statement here

String str = new String("Hello");

両方のステートメントは同じことをしますが、一方は他のステートメントよりはるかに便利です。しかし、フードの下では、彼らは編集後もほとんど同じことをします。

0
追加された
@vijay、素敵な発見!
追加された 著者 jh314,
私は両方が同じことをしているとは確信していません。 2番目のコードスニペットはコンストラクターの呼び出しになります。最初のものはそうしないでしょう。ここにコードスニペットをコンパイルした後のバイトコードの表現があります: gist.github.com/VijayKrishna/5834992
追加された 著者 vijay,
ありがとう@ jh314私はあなたがそう思ってうれしいです。私はまだJITがそれをコンパイルするかもしれないのだろうか、それは私が確信していないと言った理由だ。 :)
追加された 著者 vijay,
@PierreRymiortz、あなたの端末/コマンドプロンプトでこのコマンドを実行するだけです: javap -c <.class拡張子を持たないクラスファイルの名前>
追加された 著者 vijay,
-1の最初の例は、文字列リテラルの例であり、オブジェクトを作成することさえできないかもしれませんが、2番目の例は、文字列リテラルを使った明示的な構築であり、2つのオブジェクトを作成することができます。 (1人は拘束されていない)。
追加された 著者 Tim Bender,
EclipseのようなIDEで.classファイルを読んでください。標準jdkにはツールもありますが、 javap と思っていますが、私は使っていません。
追加された 著者 Tim Bender,
@vijayとても面白いです。あなたが私に尋ねる気にならないなら、コンパイルした後、どのようにバイトコード表現にアクセスしますか?
追加された 著者 Pierre Rymiortz,