java中的数组初始化

One*_*ree 33 java arrays int

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

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

但我不明白以下是非法的:

for (int n : {1, 2, 3})
   System.out.println(n);
Run Code Online (Sandbox Code Playgroud)

从编译器编写者的角度来看,这并没有引入任何含糊之处,是吗?可以预期数组的类型与先前声明的元素的类型相同.换句话说,n声明为int,所以数组必须是int[]

Eng*_*uad 36

你需要这个语法:

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

  • 这不是原因 - 见第一个例子.原因是在第二个例子中,编译器不知道`{1,2,3}`是什么类型.至于*为什么* - 这只是一个设计决定.一种替代方案是某种形式的类型推断,即猜测类型应该是什么. (7认同)

Mak*_*oto 36

从Java语言规范,§10.6 - 数组初始化器:

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

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

每个变量初始值设定项必须与数组的组件类型进行赋值兼容(第5.2节),否则会发生编译时错误.

如果要初始化的数组的组件类型不可恢复,则为编译时错误(第4.7节).

数组初始值设定项是数组创建表达式的一部分,它确定您需要以下四种形式之一来成功初始化数组:

ArrayCreationExpression:
    new PrimitiveType DimExprs Dimsopt
    new ClassOrInterfaceType DimExprs Dimsopt
    new PrimitiveType Dims ArrayInitializer 
    new ClassOrInterfaceType Dims ArrayInitializer
Run Code Online (Sandbox Code Playgroud)

再次,从规格:

如果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};
Run Code Online (Sandbox Code Playgroud)

主要区别在于它们在字节码中编译为什么.一个显然是一个int,另一个显然是一个短.但是,如果没有能够分辨哪个数据类型(没有数组中的值超过Short.MAX_VALUE),就不可能断言,这个数组超出了疑问的范围,是一个int.回想一下,a short落入a 的范围内int,因此在使用时可以轻松进入一些棘手/怪异的场景.

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

for(int i : arr2) {
    System.out.println(i);
}
Run Code Online (Sandbox Code Playgroud)

同样,只要元素arr2不超过Short.MAX_VALUE,你就可以在short和之间摒弃这种模糊的引用int.

这是编译器不能仅仅推断出你的意思的另一个原因int.你可能意味着short*.

*:并不是很多人会这么做,但这只是为了以防万一.


Chr*_*ers 7

因为数组是对象,必须实例化.Java不会将{}本身识别为数组.但是,它允许您使用代码块(即{..}中的代码)来定义数组的初始元素.

您完成此操作的方式由上面的答案描述.

  • 无论你是指新的byte [],new char [],new short [],new int []还是new long [],它都必须使用可能为零的上下文.它不能.所以它只有在有足够类型上下文的情况下才合法.这意味着它在语法上是合法的,但在某些情况下在语义上是非法的.你可以看到它的发展方向. (7认同)