Java: разрешение перегруженного метода и varargs - запутанный пример
Просто когда я подумал, что понял JLS15.12 применительно к varargs, вот этот пример:
package com.example.test.reflect;
public class MethodResolutionTest2 {
public int compute(Object obj1, Object obj2) {
return 42;
}
public int compute(String s, Object... objects)
{
return 43;
}
public static void main(String[] args) {
MethodResolutionTest2 mrt2 = new MethodResolutionTest2();
System.out.println(mrt2.compute("hi", mrt2));
System.out.println(mrt2.compute("hi", new Object[]{mrt2}));
System.out.println(mrt2.compute("hi", new Object[]{mrt2, mrt2, mrt2}));
}
}
который распечатывает
42
43
43
Я понимаю первую строку: JLS15.12 говорит, что разрешение метода происходит поэтапно, а фазы 1 и 2 игнорируют методы varargs, чтобы выяснить, существует ли совместимый метод, причем фаза 3 (включая varargs) происходит только в случае сбоя фаз 1 и 2. (См. JLS и этот ТАК вопрос.) Так compute(String s, Object... objects)
всегда игнорируется, если compute(Object obj1, Object obj2)
применяется.
Но я не понимаю, почему 43 напечатаны для двух других строк. Object[]
также является примером Object
Так почему же он соответствует методу varargs?
редактировать:
...и это
Object arg2 = new Object[]{mrt2};
System.out.println(mrt2.compute("hi", arg2));
печать 42
,
2 ответа
В разделе 8.4.1:
Если последний формальный параметр является переменным параметром arity типа
T
считается, что он определяет формальный параметр типаT[]
,
Поскольку вы явно предоставляете массив, это позволяет вторым двум вызовам соответствовать методу переменной arity на первом этапе, без учета переменной arity.
Методы Vararg могут вызываться с несколькими параметрами (a, b, c) или в виде массива ({a, b, c}). Поскольку вы передаете массив, соответствующий типу переменных, он имеет приоритет.
Ссылка: http://java.sun.com/docs/books/jls/third_edition/html/classes.html