56

重複の可能性:
配列定数は初期化エラーでのみ使用できます

私は配列を勉強していましたが、配列を 1 行で宣言して初期化するこの近道方法にたどり着きました。例えば、

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

しかし、次のコードを実行しようとすると、「配列定数は初期化子でのみ使用できます」というコンパイラ エラーが発生しました。

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

なんでそうなの?

4

4 に答える 4

108

JLSがそう言っているので許可されていません。この構文は、宣言と配列作成式でのみ使用できます。

後者は、同じ結果を達成する別の方法を提供します。

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

を必要とする実際の根本的な理由についてnew T[]は、次のように推測します。次の配列初期化子を検討してください。

{1, 2, 3, 4}

さまざまなタイプの配列を初期化するために使用できます。

new int[]{1, 2, 3, 4};
new float[]{1, 2, 3, 4};
new double[]{1, 2, 3, 4};

ビットが必要ない場合、セマンティック分析中にnew T[]ベアが問題を引き起こす可能性があると思います。{1, 2, 3, 4}ここでは、次のような場合を考えています。

void f(float[] x) { ... }
void f(double[] x) { ... }
void g() {
  f({1, 2, 3, 4});
}

この構文が許可されている場合、言語仕様は、呼び出す関数を選択する複雑さに対処する必要があります。

同様に、 の型が何であるべきかは明確ではありません{null}Object[]、などInteger[]になりますSerializable[]

最後に、空の配列{}は最も扱いにくいものです。ここでは、それがオブジェクトの配列なのかスカラーの配列なのかさえわかりません。

これらすべての複雑さに対処する代わりに、言語設計者はnew T[]構文を要求することで複雑さを回避することを選択したようです。

于 2012-05-09T16:57:41.497 に答える
7

短い答えは、言語仕様がそう言っているからです。

なぜですか?入力にかかっていると思われます。最初のケースでは、パーサー/コンパイラーはそれが配列変数を初期化するコンテキスト内にあることを認識しているため、中括弧は配列初期化子であると推測できます。

後者の場合、中括弧が何を意味するかは行からすぐにはわかりません。おそらく、タイパーは解析の後のフェーズで実行されるため、単純に意味を推測することはできません。

この引数は、型を再度明示的に (そして技術的に冗長に) 宣言すると、非常によく似た構文を使用できるという点で重要なようです。

int[] a;
// then later
a = new int[] { 1, 2, 3, 4 };
于 2012-05-09T17:00:24.343 に答える
2

あなたが得ることができる唯一の答えは、哲学的な性質のものです。暗黙の配列型を許可しないという決定は、物事を単純かつ明確に保つという Java の一般的な設計原則に沿っています。同じように、すべてのダウンキャストが明示的でなければならない理由、またはすべての縮小型変換が必要な理由を尋ねることができます。Java はブルーカラー言語であり、明白かつ明示的であることがそのコアバリューです。

于 2012-05-09T18:20:39.187 に答える
0

Java では、最初のメソッドを使用してのみ配列を初期化できます。配列を割り当てることはできません。その理由を理解するには、配列の実装方法に関するいくつかの理論が必要になる場合があります。コンパイラは、配列が宣言されているときに配列の大きさを知る必要があるため、最初の行で宣言と初期化を行うと、コンパイラはサイズを推測できますが、2 行目では推測できません。

于 2012-05-09T16:57:05.903 に答える