They may look similar, and they may behave similarly, but they are indeed different.
The first declaration you have is an array initializer. It can only be used when you're declaring a field or variable (as you are with int[] a = {1, 2, 3, 4, 5, 6}
), or as part of the second form, an array creation expression.
The array initializer requires a reifiable type in order for it to be valid syntax. This means that you cannot use it to create a generic array. As an example:
public class Example<T> {
public void doStuff(T first, T second, T third) {
// Invalid; T is not a reifiable type
T[] stuff = {first, second, third};
}
public void doStuff(int first, int second, int third) {
// Valid; int is reifiable
int[] stuff = {first, second, third};
}
}
The second declaration that you have is an array creation expression. It allows for several forms of declaring an array. It also allows you to create generic arrays through some rather forced casting.
To the question of why the third syntax is invalid: below is an excerpt of the ArrayCreationExpression.
ArrayCreationExpression:
new PrimitiveType DimExprs Dims (optional)
new ClassOrInterfaceType DimExprs Dims (optional)
new PrimitiveType Dims ArrayInitializer
new ClassOrInterfaceType Dims ArrayInitializer
DimExprs:
DimExpr
DimExprs DimExpr
DimExpr:
[ Expression ]
Dims:
[ ]
Dims [ ]
Effectively, the reason the syntax new int[5]{1, 2, 3, 4, 5}
is invalid is because of the above.
int[5]{1, 2, 3, 4, 5}
contains a DimsExpr
, which is the [5]
piece, and an ArrayInitializer
, which is the {1, 2, 3, 4, 5}
piece. The above language specification does not allow for both a DimsExpr(s)
and an ArrayInitializer
to be declared together.