Array initialisation in java
I noticed one could write code like this, which is perfectly normal, by the way:
int arrays[] = {1, 2, 3};
for (int n : arrays)
System.out.println(n);
But I don't see how the following is illegal:
for (int n : {1, 2, 3})
System.out.println(n);
From a compiler writer's point of view, this does not introduce any ambiguity, does it? The type of the array can be expected to be the same type as the element declared previously. In other words, n
is declared as int
, so the array must be int[]
Solution 1:
You need this syntax:
for(int n : new int[]{1, 2, 3})
System.out.println(n);
Solution 2:
From the Java Language Specification, §10.6 - Array Initializers:
An array initializer is written as a comma-separated list of expressions, enclosed by braces { and }.
A trailing comma may appear after the last expression in an array initializer and is ignored.
Each variable initializer must be assignment-compatible (§5.2) with the array's component type, or a compile-time error occurs.
It is a compile-time error if the component type of the array being initialized is not reifiable (§4.7).
An array initializer is part of an array creation expression, which does define that you require one of these four forms to successfully initialize an array:
ArrayCreationExpression: new PrimitiveType DimExprs Dimsopt new ClassOrInterfaceType DimExprs Dimsopt new PrimitiveType Dims ArrayInitializer new ClassOrInterfaceType Dims ArrayInitializer
Again, from the specs:
It is a compile-time error if the ClassOrInterfaceType does not denote a reifiable type (§4.7). Otherwise, the ClassOrInterfaceType may name any named reference type, even an abstract class type (§8.1.1.1) or an interface type (§9).
This is why you require the syntax new int[] {1, 2, 3}
.
EDIT: To get more into the nuances of your question:
From a compiler writer's point of view, this does not introduce any ambiguity, does it? The type of the array can be expected to be the same type as the element declared previously. In other words, n is declared as int, so the array must be int[]
No. There is ambiguity. As a for-instance, what is the difference between the following two statements?
int[] arr1 = new int[] {1, 2, 3};
short[] arr2 = new short[] {1, 2, 3};
The major difference is what they compile down to in bytecode. One is obviously an int, the other is obviously a short. However, without the ability to tell which data type is which (without the values in the array exceeding Short.MAX_VALUE
), it would be impossible to assert that, this array, beyond a shadow of a doubt, is an int
. Recall that a short
falls into the range of an int
, so you can easily get into some tricky/bizarre scenarios when using that.
It gets more fun: this is valid code.
for(int i : arr2) {
System.out.println(i);
}
Again, as long as the elements in arr2
don't exceed Short.MAX_VALUE
, you can get away with this ambiguous reference between short
and int
.
This is another reason why the compiler can't just infer that you mean int
. You could mean short
.*
*: Not that many people ever would, but that's just in case there are that do.