为什么只能在初始化程序中使用数组常量?

可能重复:
数组常量只能用于初始化程序错误

我正在学习数组,并且通过这种在一行中声明和初始化数组的简捷方法。 例如,

int[] a = {1, 2, 3, 4, 5}; 

但是当我试图做下面的代码,我得到这个编译器错误说:“数组常量只能用于初始化”。

 int[] a; a = {1, 2, 3, 4}; 

为什么这样?

这是不允许的,因为JLS这样说 。 语法只能在声明和数组创buildexpression式中使用。

后者提供了实现相同结果的另一种方式:

 int[] a; a = new int[]{1, 2, 3, 4}; 

至于要求new T[]的实际内在原因,我的猜测如下。 考虑下面的数组初始值设定项:

 {1, 2, 3, 4} 

它可以用来初始化不同types的数组:

 new int[]{1, 2, 3, 4}; new float[]{1, 2, 3, 4}; new double[]{1, 2, 3, 4}; 

如果不需要new T[]位,我怀疑{1, 2, 3, 4}在语义分析过程中可能会造成困难。 在这里,我正在考虑如下情况:

 void f(float[] x) { ... } void f(double[] x) { ... } void g() { f({1, 2, 3, 4}); } 

如果允许这种语法,语言规范将不得不处理select调用哪个函数的复杂性。

类似地,不清楚{null}应该是什么types。 它可以是Object[]Integer[]Serializable[]等。

最后,空arrays{}将是最棘手的。 在这里,我们甚至不知道它是一个对象数组还是一个标量数组。

而不是处理所有这些复杂性,似乎语言devise者select通过要求new T[]语法来避免它们。

简短的回答是因为语言规范如此 。

至于为什么? 我怀疑这是打字 。 在第一种情况下,parsing器/编译器知道它是在初始化一个数组variables的上下文中,所以大括号可以被推断为一个数组初始化器。

在后一种情况下,从花线上可以看出花括号的含义。 据推测Typer运行在一个较晚的parsing阶段,所以简单地推断它的含义是不可行的。

这个论点似乎有一个重要的地方,如果你专门(在技术上是冗余的)再次声明types,你可以使用一个非常类似的语法:

 int[] a; // then later a = new int[] { 1, 2, 3, 4 }; 

我java你只能使用第一种方法初始化一个数组。 你不能分配一个数组。 理解为什么可能涉及一些理论如何实现数组。 编译器必须知道在声明数组时声明了多大的数组,因此在第一行中声明和初始化时,编译器可以推断大小,而不是第二行。

你能得到的唯一答案是哲学性的。 不允许隐式数组types的决定符合Java的一般devise原则,使事情简单明了。 同样,你可以问为什么每一个沮丧必须是明确的,或每一个缩小types转换。 Java是一门蓝领语言,显而易见的是它的核心价值。