Why can array constants only be used in initializers? [duplicate]

Possible Duplicate:
Arrays constants can only be used in initializers error

I was studying arrays, and I came through this short-cut method of declaring and initializing an array in one line. For example,

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

But when I tried to do following code, I got this compiler error saying "Array constants can only be used in initializer".

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

Why so?


It's not allowed because the JLS says so. The syntax is only permitted in declarations and in array creation expressions.

The latter provide an alternative way of achieving the same result:

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

As to the actual underlying reason for requiring the new T[], my guess is as follows. Consider the following array initializer:

{1, 2, 3, 4}

It can be used to initialize arrays of different types:

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

If the new T[] bit wasn't required, I suspect that the bare {1, 2, 3, 4} could cause difficulties during semantic analysis. Here, I am thinking about cases like:

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

If this syntax were allowed, the language spec would have to deal with the complexity of choosing which function to call.

In a similar vein, it's not clear what should be the type of {null}. It can be Object[], Integer[], Serializable[] and so on.

And finally, the empty array {} would be the trickiest of all. Here, we can't even tell if it's an array of objects or an array of scalars.

Instead of dealing with all these complexities, it seems that the language designers chose to avoid them by requiring the new T[] syntax.


The short answer is because the language spec says so.

As for why? I suspect it's down to typing. In the first case, the parser/compiler knows it's within the context of initialising an array variable, and so the curly braces can be inferred to be an array initialiser.

In the latter case, it's not immediately clear from the line what the curly braces mean. Presumably the typer runs at a later phase of parsing, such that it wasn't feasible to simply infer the meaning.

This argument seems to have weight in that you can use a very similar syntax if you specifically (and technically redundantly) declare the type again:

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

The only answer you can get is of philosophical nature. The decision not to allow the implicit array type is in line with the general design principle of Java to keep things simple and obvious. In the same vein you could ask why every downcast must be explicit, or every narrowing type-conversion. Java is a blue-collar language and obvious+explicit is its core value.