56

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

我正在研究数组,我通过这种在一行中声明和初始化数组的捷径获得了。例如,

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

但是当我尝试执行以下代码时,我得到了这个编译器错误,说“数组常量只能在初始化程序中使用”。

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

为什么这样?

4

4 回答 4

108

这是不允许的,因为JLS 这么说。该语法仅允许在声明和数组创建表达式中使用。

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

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

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

{1, 2, 3, 4}

它可用于初始化不同类型的数组:

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});
}

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

同样,不清楚应该是什么类型的{null}. 它可以是Object[], Integer[],Serializable[]等等。

最后,空数组{}将是最棘手的。在这里,我们甚至无法判断它是对象数组还是标量数组。

语言设计者似乎选择通过要求new T[]语法来避免这些复杂性,而不是处理所有这些复杂性。

于 2012-05-09T16:57:41.497 回答
7

简短的回答是因为语言规范是这么说的

至于为什么?我怀疑这取决于打字。在第一种情况下,解析器/编译器知道它在初始化数组变量的上下文中,因此可以推断花括号是数组初始化器。

在后一种情况下,花括号的含义并不清楚。推测打字机在解析的后期运行,因此简单地推断含义是不可行的。

这个论点似乎很重要,因为如果您专门(并且在技术上是多余的)再次声明该类型,您可以使用非常相似的语法:

int[] a;
// then later
a = new int[] { 1, 2, 3, 4 };
于 2012-05-09T17:00:24.343 回答
2

你能得到的唯一答案是哲学性质的。不允许隐式数组类型的决定符合 Java 的一般设计原则,以使事情简单明了。同样,您可能会问为什么每次向下转换都必须是显式的,或者每次缩小类型转换。Java是蓝领语言,明显+显式是它的核心价值。

于 2012-05-09T18:20:39.187 回答
0

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

于 2012-05-09T16:57:05.903 回答