Подтвердить что ты не робот

Почему в Java не разрешено перегружать Foo (Object...) с помощью Foo (Object [])?

Мне было интересно, почему в 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());

Есть ли причина в этом?

4b9b3361

Ответ 1

Этот 15.12.2.5 Выбор наиболее конкретного метода об этом говорит, но его довольно сложно. например Выбор между 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) {

Способ сделать их разными - это взять один аргумент перед 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.

Ответ 2

Самый прямой ответ на вопрос состоит в том, что наличие обеих деклараций создало бы двусмысленность в логике поиска метода. Если вы объявили оба в одном классе, не было бы способа выяснить, какой метод вы хотели бы при вызове:

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

И Java требует, чтобы всегда существовал наиболее специфический метод для каждого вызова метода. Для чего, см. Ответ Питера.