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

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

我正在研究数组,并且经历了这种在一行中声明和初始化数组的捷径。 例如,

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

但是,当我尝试执行以下代码时,出现此编译器错误,提示“数组常量只能在初始化程序中使用”。

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

为什么这样?

Ritika Srivastava Misra asked 2020-02-13T23:38:25Z
4个解决方案
97 votes

这是不允许的,因为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[]位,我怀疑裸露的Object[]可能会在语义分析过程中造成困难。 在这里,我正在考虑以下情况:

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

如果允许使用此语法,则语言规范将必须处理选择要调用的函数的复杂性。

同样,不清楚new T[]的类型应该是什么。可以是Object[]Integer[]Serializable[],依此类推。

最后,空数组new T[]将是最棘手的数组。 在这里,我们甚至无法分辨它是对象数组还是标量数组。

语言设计人员似乎没有解决所有这些复杂问题,而是选择了new T[]语法来避免它们。

NPE answered 2020-02-13T23:39:15Z
6 votes

简短的答案是因为语言规范是这样说的。

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

在后一种情况下,尚不清楚从行中大括号的含义。 大概是打字机在解析的后期运行,所以简单地推断含义是不可行的。

该参数似乎很重要,因为如果再次(特别是技术上多余)声明类型,则可以使用非常相似的语法:

int[] a;
// then later
a = new int[] { 1, 2, 3, 4 };
Andrzej Doyle answered 2020-02-13T23:39:50Z
1 votes

您可以获得的唯一答案是哲学性的。 不允许使用隐式数组类型的决定符合Java的一般设计原则,以使事情简单明了。 同样,您可能会问为什么每个下调都必须是明确的,还是每个缩小的类型转换都必须如此。 Java是一种蓝领语言,其核心价值是显而易见的。

Marko Topolnik answered 2020-02-13T23:40:10Z
0 votes

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

cobie answered 2020-02-13T23:40:30Z
translate from https://stackoverflow.com:/questions/10520617/why-can-array-constants-only-be-used-in-initializers