【问题标题】:Why can array constants only be used in initializers? [duplicate]为什么数组常量只能在初始化器中使用? [复制]
【发布时间】:2012-05-09 16:54:32
【问题描述】:

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

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

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

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

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

为什么会这样?

【问题讨论】:

  • 这不是重复的。 OP 在问 why 而不是 how
  • 咩;不相信这是一个欺骗 - 链接的问题说“我该怎么做才能使它起作用”,这个问题问“为什么其他方式实际上不起作用”。这种差异导致了完全不同的答案——这个问题已经有了如何让它发挥作用。
  • 这类问题很有趣,但几乎不可能回答——我们所能做的就是推测。不过,向编写规范的那部分的人询问这个问题真的很有趣,作为一个教学时刻(你为什么做这个设计而不是那个?)。
  • 我已经通过它我知道声明和初始化数组的方法 jst 想知道为什么上面不允许。他们背后有什么合乎逻辑的原因吗?

标签: java


【解决方案1】:

这是不允许的,因为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[] 语法来避免这些复杂性,而不是处理所有这些复杂性。

【讨论】:

  • 我知道,但我的问题是为什么不允许这样做?
  • 嗯——编译器知道arrn的类型。我可以买它是一个编译器简化,但没有什么难的。
  • @DaveNewton:不一定。考虑将裸{1, 2, 3, 4} 传递到为float[]double[] 重载的函数的可能性。应该怎么办?
  • @aix 现在当它不是一个数组时会发生同样的事情,它会调用float[] 方法。
  • 现在真的发生了吗?这不是意味着编译器通过数组,尽可能多地对其进行转换,然后选择构造函数吗?我很高兴这是不允许的......
【解决方案2】:

简短的回答是because the language spec says so

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

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

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

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

【讨论】:

  • Java 以其“技术冗余”的语法而闻名;没有关于它的“技术”。
【解决方案3】:

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

【讨论】:

    【解决方案4】:

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

    【讨论】:

    • OP 已经知道第二个不起作用并询问为什么。答案根本没有解决这个问题。
    • 为什么编译器不能读取花括号中的元素并知道它在第一种情况下的大小 - int[] a={1,2,3};
    • java 是静态类型的,因此编译器必须在初始化时知道​​数组的大小,以便为数组分配内存。
    猜你喜欢
    • 2011-11-18
    • 1970-01-01
    • 2013-04-26
    • 2011-01-22
    • 2011-09-14
    • 2015-07-09
    • 2011-05-26
    相关资源
    最近更新 更多