来自 Java 语言规范,§10.6 - Array Initializers:
数组初始值设定项以逗号分隔的列表形式写入
表达式,用大括号 { 和 } 括起来。
一个尾随逗号可能出现在数组中的最后一个表达式之后
初始化器并被忽略。
每个变量初始化器必须与赋值兼容(第 5.2 节)
数组的组件类型,或发生编译时错误。
如果数组的组件类型为
初始化是不可具体化的(§4.7)。
数组初始化器是array creation expression 的一部分,它确实定义了您需要以下四种形式之一才能成功初始化数组:
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。回想一下short 属于int 的范围,因此在使用它时很容易遇到一些棘手/奇怪的场景。
变得更有趣:这是有效代码。
for(int i : arr2) {
System.out.println(i);
}
同样,只要arr2 中的元素不超过Short.MAX_VALUE,您就可以摆脱short 和int 之间的这种模棱两可的引用。
这是编译器不能仅仅推断您的意思是int 的另一个原因。你可能是指short.*
*:没有多少人会,但那只是以防万一有做。