为什么数组常量只能用于初始值设定项?

时间:2012-05-09 16:54:32

标签: java

  

可能重复:
  Arrays constants can only be used in initializers error

我正在研究数组,我通过这种在一行中声明和初始化数组的简短方法。例如,

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

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

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

为什么会这样?

4 个答案:

答案 0 :(得分:93)

这是不允许的,因为JLS says so。语法仅在声明和数组创建表达式中允许。

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

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[]语法来避免它们。

答案 1 :(得分:5)

简短回答是because the language spec says so

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

在后一种情况下,从线上不能立即清楚花括号的含义。据推测,typer在解析的后期阶段运行,因此简单地推断其意义是不可行的。

这个论点似乎很重要,如果你特意(并且在技术上冗余地)再次声明类型,你可以使用非常相似的语法:

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

答案 2 :(得分:0)

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

答案 3 :(得分:0)

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