为什么Java中不允许用Foo(Object )重载Foo(Object …)?

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

 Foo(Object[] args){} 

使用如下:

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

而另一种forms:

 Foo(Object... args){} 

使用如下:

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

这背后有什么理由吗?

这个15.12.2.5选择最具体的方法谈论这个,但它非常复杂。 例如,在Foo(Number … int)和Foo(Integer … int)之间选择

为了向后兼容,这些实际上是相同的。

 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) { 

使它们与众不同的一种方法是在varargs之前采用一个参数

 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. 

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

 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. 

另外,varags必须是最后一个参数。

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

这个问题最直接的答案是,两个声明都会在方法查找逻辑中产生歧义。 如果你在同一个类中声明了两个,那么在调用时就无法找出你想要的方法:

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

Java要求每个方法调用总是有一个最具体的方法。 为什么 ,请看彼得的回答。