在 Java 中,为什么这个语法有效而这个无效?

In Java why is this syntax valid and this isn't?

我知道这两个都是有效的并且意思完全一样:

首选:

void foo(int[] bar){
    // do something 
}

不喜欢:

void foo(int bar[]){
    // do something
}

我不明白的是,按照上面相同的逻辑,为什么这无效?

void foo(int... bar[]){
    // do something 
}

但这是:

void foo(int[]... bar){
    // do something 
}

在Java中,确实可以用

这样的2种形式声明数组
int[] arr;

int arr[];

第二个通常不是首选,因为括号标识数组类型并且应该与类型名称一起出现。简单来说,可以遵循

的约定
type variable; 

使用数组使用的第一个模型构建所有代码。

现在问题来了,这正是不支持以 int... arr[] 形式使用 varargs 的原因。 varargs指定特定类型的任意计数性质。

所以对于类型规范 int... 它意味着整数值的任意计数,而 int[]... 意味着整数数组的任意数量。 varargs 支持将变量用作其类型而不是数组。所以 int... arr[] 是一个错误。

让我们从 int bar[] 对比 int[] bar 开始。前者是原始 Java 1.0 中包含的一些语法糖,供从 C 或 C++ 过渡的程序员使用。 Java 语法有点“疣”……现在大多数人认为支持它是错误的。规范本身、教程、书籍和... Java 样式检查器不鼓励您使用它。

所以在 Java 的后期(在 Java 5 中)他们添加了 ... 语法来支持方法调用中的“varargs”功能。好的。但它们不包括对句法疣的支持。

为什么?

  • 做出决定时我们不在场……所以我们真的不知道为什么。
  • 因为原来的疣是个坏主意
  • 因为 C/C++ 不以这种方式支持可变参数,所以它对过渡器没有帮助。
  • 因为int... bar[]在视觉上有歧义1。它是“int 数组的可变参数”还是“int 的可变参数数组”?即使是 C 和 C++ 也不允许您编写 int[] bar[],这大致就是 this 映射到的内容。
  • 因为(坦率地说)void foo(int... bar[]) 看起来 讨厌

1 - 也许实际上并不模糊,因为“int 可变参数数组”的解释没有意义。但是,这并不能避免假设语法可能导致的混淆。最好避免问题……就像他们那样。