这两种数组声明方式有什么区别?

3
请解释一下两种数组声明方式的区别。
int[] a = {5, 7, 8, 9, 6};

并且。
int[] arr = new int[]{5, 7, 8, 9, 6};

第一种情况下没有进行内存分配,而第二种情况下对每个元素都进行了内存分配,这是这两种情况的区别。

此外,为什么下面的声明会导致错误?

int[] arr = new int[5]{5, 7, 8, 9, 6};

这不是重复的问题,因为这个问题询问这两种语法之间的区别,而不是如何创建一个数组。 - Makoto
3个回答

2
它们可能看起来相似,而且它们的行为也可能相似,但它们确实不同。
你第一个声明是一个数组初始化器。它只能在声明字段或变量时使用(就像你使用 int[] a = {1, 2, 3, 4, 5, 6} 一样),或者作为第二种形式——数组创建表达式的一部分。
数组初始化器需要一个可具体化类型才能成为有效的语法。这意味着你不能使用它来创建泛型数组。例如:
public class Example<T> {

    public void doStuff(T first, T second, T third) {
        // Invalid; T is not a reifiable type
        T[] stuff = {first, second, third};
    }

    public void doStuff(int first, int second, int third) {
        // Valid; int is reifiable
        int[] stuff = {first, second, third};
    }
}

你所拥有的第二个声明是一个数组创建表达式。它允许多种形式的数组声明。通过一些强制转换,它还可以创建通用数组
至于为什么第三个语法是无效的问题:下面是ArrayCreationExpression的摘录。
  ArrayCreationExpression:
      new PrimitiveType DimExprs Dims (optional)
      new ClassOrInterfaceType DimExprs Dims (optional)
      new PrimitiveType Dims ArrayInitializer 
      new ClassOrInterfaceType Dims ArrayInitializer

  DimExprs:
      DimExpr
      DimExprs DimExpr

  DimExpr:
      [ Expression ]

  Dims:
      [ ]
      Dims [ ]
实际上,new int[5]{1, 2, 3, 4, 5} 这个语法无效的原因是因为上面提到的问题。 int[5]{1, 2, 3, 4, 5} 包含一个 DimsExpr,即 [5] 部分,和一个 ArrayInitializer,即 {1, 2, 3, 4, 5} 部分。上述语言规范不允许同时声明 DimsExpr(s)ArrayInitializer

0

前两个声明没有区别。最后一个声明指定了数组的长度两次。我认为这是无效的,以避免编译器匹配这两个指定的大小。


这不正确。这实际上是语言词法分析器是否支持该语法的问题。如果语言不支持该语法,则对于使用该语法声明的对象可能发生的情况的假设是无关紧要的。 - Makoto
对于软件工程来说,这并不是无关紧要的。任何Java架构师都会告诉你,Java试图保持其语法与良好实践的一致性,这也是我们在已经有一个相同目的的表达式后获得增强的<>表达式的原因。 - Victor
@Victor 我从未暗示过这是无关紧要的。相反,解决潜在的歧义需要更多的努力。 - Tarik
@Makoto 是的,任何语法都可以被支持,包括那些麻烦的。Java团队显然选择通过防止过度指定数组长度参数来避免潜在的歧义。 - Tarik
抱歉 @Tarik,我说的是他的评论,不是你的回答。 - Victor

0

前两者没有区别,因为它们都需要分配内存。

然而,第三个是不正确的,因为它有重复的信息。如果您使用{x,y,z},则元素数量是隐含的,您不需要或不应该在[number_elements]上重复此信息。特别是因为这些信息可能是不一致的,例如[2]{x,y,z}。

来自Oracle文档页面:在这里,数组的长度由大括号和逗号分隔的值的数量确定。

这也是为什么int[]{5,7,8,9,6}是完全可以的。

现在,如果您没有初始值{},那么就没有信息;因此需要[number]。


第二个声明中没有重复的信息。语言词法分析器只是不支持它。 - Makoto
从文档中:在这里,数组的长度由大括号之间提供的逗号分隔值的数量确定。 - Victor
你是对的,没有正确的方法,我只是在说为什么不是一个有效的语法,而不是只说它不受支持。 - Victor
但它不是有效的语法的原因是因为该语法不受支持。这就是我在这里想表达的全部。您可以查看我的答案并单击JLS引用以更好地理解。 - Makoto
你的回答是正确的,但它很简单,因为它就是这样。你用语法来说语法不正确。确实,语法是这么说的,但有人出于某种原因写了它。抱歉不同意你的观点,我理解你的意思,但我们的答案并不冲突,如果你仔细想想,我们采取了不同的方法。顺便说一句,不需要告诉别人去学习,这有点粗鲁,讨论总是好的。 - Victor
显示剩余3条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接