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

时间:2012-01-12 16:14:11

标签: java methods parameters arguments language-specifications

我想知道为什么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());

这背后有什么理由吗?

2 个答案:

答案 0 :(得分:25)

这个15.12.2.5 Choosing the Most Specific Method谈论这个,但它非常复杂。例如选择Foo(Number ... int)和Foo(Integer ... ints)

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

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

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

e.g。你可以将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.

答案 1 :(得分:3)

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

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

Java要求每个方法调用总是有一个最具体的方法。 对于 why ,请参阅Peter的回答。