【问题标题】:Why is it not allowed in Java to overload Foo(Object...) with Foo(Object[])?为什么 Java 中不允许用 Foo(Object[]) 重载 Foo(Object...)?
【发布时间】:2012-02-08 22:25:37
【问题描述】:

我想知道为什么在 Java 中不允许使用 Foo(Object[] args) 重载 Foo(Object[] args),尽管它们的使用方式不同?

Foo(Object[] args){}

用法如下:

Foo(new Object[]{new Object(), new Object()});

而另一种形式:

Foo(Object... args){}

用法如下:

Foo(new Object(), new Object());

这背后有什么原因吗?

【问题讨论】:

  • 我可能遗漏了一些东西,但你为什么需要超载?如果您将您的方法声明为 void foo(Object... args),那么您可以使用 either foo(new Object(), new Object()) or foo(new Object[] { new Object(), new Object() }) 调用它并获得相同的结果。有关示例,请参见 this related question
  • 可变参数只是将最后声明的数组(如int[]Object[])转换为可变参数类型的方法签名的标志。除此之外 - 方法签名之间没有区别。同样的问题是不能重载privatepublic 方法。

标签: java methods parameters arguments language-specifications


【解决方案1】:

这个15.12.2.5 Choosing the Most Specific Method 讲这个,不过挺复杂的。例如在 Foo(Number... ints) 和 Foo(Integer... ints) 之间进行选择

为了向后兼容,它们实际上是一回事。

public Foo(Object... args){} // syntactic sugar for Foo(Object[] args){}

// calls the varargs method.
Foo(new Object[]{new Object(), new Object()});

例如您可以将 main() 定义为

public static void main(String... args) {

使它们不同的一种方法是在可变参数之前采用一个参数

public Foo(Object o, Object... os){} 

public Foo(Object[] os) {}

Foo(new Object(), new Object()); // calls the first.

Foo(new Object[]{new Object(), new Object()}); // calls the second.

它们并不完全相同。细微的差别在于,虽然您可以将数组传递给可变参数,但您不能将数组参数视为可变参数。

public Foo(Object... os){} 

public Bar(Object[] os) {}

Foo(new Object[]{new Object(), new Object()}); // compiles fine.

Bar(new Object(), new Object()); // Fails to compile.

此外,可变参数必须是最后一个参数。

public Foo(Object... os, int i){} // fails to compile.

public Bar(Object[] os, int i) {} // compiles ok.

【讨论】:

  • +1 很好的解释。是否为此编写了任何语言规范?
  • 请看this question
【解决方案2】:

对这个问题最直接的回答是,同时拥有这两个声明会在方法查找逻辑中产生歧义。如果您在同一个类中声明两者,那么在调用时将无法确定您想要哪种方法:

Object[] a = new Object[10];
Foo(a); // array or vararg?

Java 要求每个方法调用始终有一个最具体的方法。 对于为什么,请参阅彼得的回答。

【讨论】:

  • 它们一模一样,没有歧义,只是不能存在于同一个类中
猜你喜欢
  • 2011-07-13
  • 1970-01-01
  • 1970-01-01
  • 2019-06-03
  • 1970-01-01
  • 2017-07-04
  • 2011-09-01
  • 2010-09-24
  • 2011-09-17
相关资源
最近更新 更多