可能重复:
数组常量只能用于初始化错误
我正在研究数组,我通过这种在一行中声明和初始化数组的捷径获得了。例如,
int[] a = {1, 2, 3, 4, 5};
但是当我尝试执行以下代码时,我得到了这个编译器错误,说“数组常量只能在初始化程序中使用”。
int[] a;
a = {1, 2, 3, 4};
为什么这样?
可能重复:
数组常量只能用于初始化错误
我正在研究数组,我通过这种在一行中声明和初始化数组的捷径获得了。例如,
int[] a = {1, 2, 3, 4, 5};
但是当我尝试执行以下代码时,我得到了这个编译器错误,说“数组常量只能在初始化程序中使用”。
int[] a;
a = {1, 2, 3, 4};
为什么这样?
这是不允许的,因为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[]
语法来避免这些复杂性,而不是处理所有这些复杂性。
简短的回答是因为语言规范是这么说的。
至于为什么?我怀疑这取决于打字。在第一种情况下,解析器/编译器知道它在初始化数组变量的上下文中,因此可以推断花括号是数组初始化器。
在后一种情况下,花括号的含义并不清楚。推测打字机在解析的后期运行,因此简单地推断含义是不可行的。
这个论点似乎很重要,因为如果您专门(并且在技术上是多余的)再次声明该类型,您可以使用非常相似的语法:
int[] a;
// then later
a = new int[] { 1, 2, 3, 4 };
你能得到的唯一答案是哲学性质的。不允许隐式数组类型的决定符合 Java 的一般设计原则,以使事情简单明了。同样,您可能会问为什么每次向下转换都必须是显式的,或者每次缩小类型转换。Java是蓝领语言,明显+显式是它的核心价值。
我java你只能使用第一种方法初始化一个数组。您不能分配数组。理解为什么可能涉及一些关于如何实现数组的理论。编译器在声明数组时必须知道数组有多大,因此在第一行的声明和初始化中,编译器可以推断出大小,但不能通过第二行推断。