来自 Java 语言规范,§10.6 - Array Initializers:
数组初始值设定项以逗号分隔的表达式列表形式编写,用大括号 { 和 } 括起来。
尾随逗号可能出现在数组初始值设定项中的最后一个表达式之后并被忽略。
每个变量初始化器必须与数组的组件类型赋值兼容(第 5.2 节),否则会发生编译时错误。
如果正在初始化的数组的组件类型不可具体化(第 4.7 节),则会出现编译时错误。
数组初始化器是数组创建表达式的一部分,它确实定义了您需要以下四种形式之一才能成功初始化数组:
ArrayCreationExpression:
new PrimitiveType DimExprs Dimsopt
new ClassOrInterfaceType DimExprs Dimsopt
new PrimitiveType Dims ArrayInitializer
new ClassOrInterfaceType Dims ArrayInitializer
再次,从规格:
如果 ClassOrInterfaceType 不表示可具体化类型(第 4.7 节),则为编译时错误。否则,ClassOrInterfaceType 可以命名任何命名的引用类型,甚至是抽象类类型(§8.1.1.1)或接口类型(§9)。
这就是您需要语法的原因new int[] {1, 2, 3}
。
编辑:要更多地了解您的问题的细微差别:
从编译器作者的角度来看,这不会引入任何歧义,不是吗?可以预期数组的类型与先前声明的元素的类型相同。换句话说,n被声明为int,所以数组必须是int[]
不,有歧义。 例如,以下两个语句有什么区别?
int[] arr1 = new int[] {1, 2, 3};
short[] arr2 = new short[] {1, 2, 3};
主要区别在于它们在字节码中编译成的内容。一个明显是int,另一个明显是short。但是,如果无法判断哪种数据类型是哪种(数组中的值不超过Short.MAX_VALUE
),就不可能断言这个数组毫无疑问是一个int
. 回想一下 ashort
属于 a 的范围int
,因此在使用它时您很容易陷入一些棘手/奇怪的场景。
它变得更有趣: 这是有效的代码。
for(int i : arr2) {
System.out.println(i);
}
同样,只要arr2
不超过中的元素Short.MAX_VALUE
,您就可以摆脱和之间的这种模棱两可的short
引用int
。
这是编译器不能仅仅推断出你的意思的另一个原因int
。你的意思可能short
是.*
*:没有多少人会这样做,但那只是以防万一。