为什么只能在初始化程序中使用数组常量?
可能重复:
数组常量只能用于初始化程序错误
我正在学习数组,并且通过这种在一行中声明和初始化数组的简捷方法。 例如,
int[] a = {1, 2, 3, 4, 5};
但是当我试图做下面的代码,我得到这个编译器错误说:“数组常量只能用于初始化”。
int[] a; a = {1, 2, 3, 4};
为什么这样?
这是不允许的,因为JLS这样说 。 语法只能在声明和数组创buildexpression式中使用。
后者提供了实现相同结果的另一种方式:
int[] a; a = new int[]{1, 2, 3, 4};
至于要求new T[]
的实际内在原因,我的猜测如下。 考虑下面的数组初始值设定项:
{1, 2, 3, 4}
它可以用来初始化不同types的数组:
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}); }
如果允许这种语法,语言规范将不得不处理select调用哪个函数的复杂性。
类似地,不清楚{null}
应该是什么types。 它可以是Object[]
, Integer[]
, Serializable[]
等。
最后,空arrays{}
将是最棘手的。 在这里,我们甚至不知道它是一个对象数组还是一个标量数组。
而不是处理所有这些复杂性,似乎语言devise者select通过要求new T[]
语法来避免它们。
简短的回答是因为语言规范如此 。
至于为什么? 我怀疑这是打字 。 在第一种情况下,parsing器/编译器知道它是在初始化一个数组variables的上下文中,所以大括号可以被推断为一个数组初始化器。
在后一种情况下,从花线上可以看出花括号的含义。 据推测Typer运行在一个较晚的parsing阶段,所以简单地推断它的含义是不可行的。
这个论点似乎有一个重要的地方,如果你专门(在技术上是冗余的)再次声明types,你可以使用一个非常类似的语法:
int[] a; // then later a = new int[] { 1, 2, 3, 4 };
我java你只能使用第一种方法初始化一个数组。 你不能分配一个数组。 理解为什么可能涉及一些理论如何实现数组。 编译器必须知道在声明数组时声明了多大的数组,因此在第一行中声明和初始化时,编译器可以推断大小,而不是第二行。
你能得到的唯一答案是哲学性的。 不允许隐式数组types的决定符合Java的一般devise原则,使事情简单明了。 同样,你可以问为什么每一个沮丧必须是明确的,或每一个缩小types转换。 Java是一门蓝领语言,显而易见的是它的核心价值。