Java 中的数组初始化

2022-09-01 08:10:34

我注意到人们可以这样写代码,顺便说一句,这是完全正常的:

int arrays[] = {1, 2, 3};
for (int n : arrays)
   System.out.println(n);

但我不认为以下内容是非法的:

for (int n : {1, 2, 3})
   System.out.println(n);

从编译器编写者的角度来看,这不会引入任何歧义,不是吗?数组的类型可以预期与之前声明的元素的类型相同。换句话说,被声明为 ,因此数组必须nintint[]


答案 1

您需要以下语法:

for(int n : new int[]{1, 2, 3})
   System.out.println(n);

答案 2

来自 Java 语言规范 §10.6 - 数组初始值设定项

数组初始值设定项编写为逗号分隔的表达式列表,用大括号 { 和 } 括起来。

尾随逗号可能出现在数组初始值设定项中的最后一个表达式之后,并被忽略。

每个变量初始值设定项必须与数组的组件类型进行赋值兼容 (§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,另一个显然是短的。但是,如果没有能力分辨哪种数据类型是哪种数据类型(如果数组中的值超过),就不可能断言,这个数组,除了一个可疑的阴影之外,是一个。回想一下,a 属于 的范围,因此在使用它时,您可以轻松地进入一些棘手/奇怪的场景。Short.MAX_VALUEintshortint

它变得更有趣:这是有效的代码。

for(int i : arr2) {
    System.out.println(i);
}

同样,只要 中的元素不超过 ,就可以摆脱 和 之间的这种模糊引用。arr2Short.MAX_VALUEshortint

这是编译器不能仅仅推断出您的意思是的另一个原因。你的意思可能是 .*intshort

*:没有多少人这样做,但这只是以防万一。