可能重复:
数组常量只能用于初始值设定项错误
我正在研究数组,我通过这种在一行中声明和初始化数组的简短方法.例如,
int[] a = {1, 2, 3, 4, 5};
Run Code Online (Sandbox Code Playgroud)
但是当我尝试执行以下代码时,我得到了这个编译器错误,说"数组常量只能在初始化程序中使用".
int[] a;
a = {1, 2, 3, 4};
Run Code Online (Sandbox Code Playgroud)
为什么这样?
NPE*_*NPE 97
这是不允许的,因为JLS这样说.语法仅在声明和数组创建表达式中允许.
后者提供了另一种实现相同结果的方法:
int[] a;
a = new int[]{1, 2, 3, 4};
Run Code Online (Sandbox Code Playgroud)
至于要求的实际根本原因new T[],我的猜测如下.考虑以下数组初始值设定项:
{1, 2, 3, 4}
Run Code Online (Sandbox Code Playgroud)
它可用于初始化不同类型的数组:
new int[]{1, 2, 3, 4};
new float[]{1, 2, 3, 4};
new double[]{1, 2, 3, 4};
Run Code Online (Sandbox Code Playgroud)
如果new T[]不需要这个位,我怀疑裸位{1, 2, 3, 4}可能会在语义分析过程中造成困难.在这里,我在考虑以下案例:
void f(float[] x) { ... }
void f(double[] x) { ... }
void g() {
f({1, 2, 3, 4});
}
Run Code Online (Sandbox Code Playgroud)
如果允许这种语法,则语言规范必须处理选择调用哪个函数的复杂性.
同样,还不清楚应该是什么类型{null}.它可以是Object[],Integer[],Serializable[]等.
最后,空阵列{}将是最棘手的.在这里,我们甚至无法判断它是一个对象数组还是一组标量.
而不是处理所有这些复杂性,似乎语言设计者选择通过要求new T[]语法来避免它们.
简短的回答是因为语言规范是这样说的.
至于为什么?我怀疑这是打字.在第一种情况下,解析器/编译器知道它在初始化数组变量的上下文中,因此花括号可以推断为数组初始化器.
在后一种情况下,从线上不能立即清楚花括号的含义.据推测,typer在解析的后期阶段运行,因此简单地推断其含义是不可行的.
这个论点似乎很重要,因为如果你特意(并且在技术上冗余地)再次声明类型,你可以使用非常相似的语法:
int[] a;
// then later
a = new int[] { 1, 2, 3, 4 };
Run Code Online (Sandbox Code Playgroud)
在 java 中,您只能使用第一种方法初始化数组。您无法分配数组。理解其中的原因可能涉及一些有关数组如何实现的理论。声明数组时,编译器必须知道数组有多大,因此通过第一行的声明和初始化,编译器可以推断出数组的大小,但不能推断出第二行的大小。
| 归档时间: |
|
| 查看次数: |
57982 次 |
| 最近记录: |