Java 为什么数组常量只能在初始值设定项中使用?
可能重复:Java 为什么数组常量只能在初始值设定项中使用?,java,Java,可能重复: 我在研究数组,通过这种简单的方法在一行中声明和初始化数组。比如说, int[] a = {1, 2, 3, 4, 5}; 但当我尝试执行以下代码时,我得到了一个编译器错误,它说“数组常量只能在初始值设定项中使用” 为什么会这样?I java只能使用第一种方法初始化数组。不能分配数组。理解为什么可能需要一些关于如何实现数组的理论。当数组被声明时,编译器必须知道数组有多大,因此在第一行声明和初始化时,编译器可以推断出数组的大小,但在第二行则不能。该语法仅允许在声明和数组创建表达式中使
我在研究数组,通过这种简单的方法在一行中声明和初始化数组。比如说,
int[] a = {1, 2, 3, 4, 5};
但当我尝试执行以下代码时,我得到了一个编译器错误,它说“数组常量只能在初始值设定项中使用”
为什么会这样?I java只能使用第一种方法初始化数组。不能分配数组。理解为什么可能需要一些关于如何实现数组的理论。当数组被声明时,编译器必须知道数组有多大,因此在第一行声明和初始化时,编译器可以推断出数组的大小,但在第二行则不能。该语法仅允许在声明和数组创建表达式中使用 后者提供了实现相同结果的替代方法:
int[] a;
a = new int[]{1, 2, 3, 4};
至于需要新T[]
的实际根本原因,我的猜测如下。考虑下面的数组初始化器:
{1, 2, 3, 4}
它可用于初始化不同类型的数组:
new int[]{1, 2, 3, 4};
new float[]{1, 2, 3, 4};
new double[]{1, 2, 3, 4};
如果不需要新的T[]
位,我怀疑裸露的{1,2,3,4}
可能会在语义分析过程中造成困难。在这里,我想到的案例如下:
void f(float[] x) { ... }
void f(double[] x) { ... }
void g() {
f({1, 2, 3, 4});
}
如果允许这种语法,语言规范将不得不处理选择调用哪个函数的复杂性
同样,不清楚{null}
的类型应该是什么。它可以是对象[]
,整数[]
,可序列化[]
等等
最后,空数组{}
将是最棘手的。在这里,我们甚至不知道它是一个对象数组还是一个标量数组
语言设计者似乎没有处理所有这些复杂的问题,而是选择使用新的T[]
语法来避免这些问题
为什么呢?我怀疑这是打字的问题。在第一种情况下,解析器/编译器知道它在初始化数组变量的上下文中,因此可以推断花括号是数组初始化器
在后一种情况下,从线条上看不清楚花括号是什么意思。大概打字机是在解析的后期运行的,因此简单地推断其含义是不可行的
这个参数似乎很重要,因为如果您再次明确(技术上是冗余的)声明类型,您可以使用非常类似的语法:
int[] a;
// then later
a = new int[] { 1, 2, 3, 4 };
你能得到的唯一答案是哲学性质的。不允许隐式数组类型的决定符合Java的一般设计原则,以使事情简单明了。同样,您也可以问为什么每次向下转换都必须是显式的,或者每次缩小类型转换都必须是显式的。Java是一种蓝领语言,显然+显式是它的核心价值。我知道,但我的问题是,为什么不允许使用这种语言?嗯——编译器知道
arrn
的类型。我可以相信这是一个编译器简化,但没有什么困难。@DaveNewton:不一定。考虑“裸<代码> { 1, 2, 3,4 } /代码>被传递到一个函数中的可能性,该函数被重载为<代码>浮点[]/COD>和<代码>双[]/CODE >。该怎么办?@aix与现在不是数组时发生的情况相同,它会调用float[]
方法。现在真的发生了吗?这难道不意味着编译器遍历数组,尽可能多地窄化它,然后选择构造函数吗?我很高兴这是不允许的…OP已经知道第二个不起作用了,并且问为什么。答案根本不能解决这个问题。为什么编译器可以读取卷曲黄铜中元素的no,并像在第一种情况下一样知道元素的大小-int[]a={1,2,3};java是静态类型的,因此编译器在初始化时必须知道数组的大小,以便为数组分配内存。这不是重复的。OP在问为什么不怎么做;不相信这是一个骗局——链接的问题是“我如何做才能让它工作”,这个问题问“为什么另一种方法实际上不工作”。这种差异导致了完全不同的答案——这个问题已经有了如何解决的方法。这类问题很有趣,但几乎不可能回答——我们所能做的就是猜测。不过,作为一个教学时刻,问一下编写规范这一部分的人,这真的很有趣(你为什么要做这个设计而不是那个?)。我已经讨论过了,我知道如何声明和初始化数组jst,我想知道上面不允许的原因。Java以其“技术上冗余”的语法而闻名;从技术上讲,这是不可能的。
int[] a;
// then later
a = new int[] { 1, 2, 3, 4 };