Рассмотрим пример
public class C {
public void method(String s, Integer i, Object... o) {
System.out.println("method(String s, Integer i, Object... o)");
}
public void method(Object o, Integer i) {
System.out.println("method(Object o, Integer i)");
}
}
Когда я выполняю
C c = new C();
c.method("1", 1);
Я ожидал, что будет вызвана первая реализация method, но я распечатал это сообщение
method(Object o, Integer i)
Я читал в характеристики, что методы с переменными аргументами (varargs) не рассматриваются в фаза 1, но мне это не интуитивно понятно.




Это потому, что вы отправили только два аргумента, поэтому будет выполнен метод с двумя параметрами, отправьте три и будет выполнен метод с тремя параметрами.
Сначала вам нужно будет понять одну из объектно-ориентированных концепций (и ее синтаксис Java) ООП, полиморфизма и перегрузки. В любом случае, позвонив
c.method("1", 1);
вы фактически вызываете второй метод, который принимает 2 параметра, а не первый, который, кажется, имеет 3 или более параметров. программа на самом деле делает то, что предполагается.
Если вам нужно вызвать первый метод, вместо этого используйте три параметра, потому что переменные-аргументы обычно принимают один или любое количество параметров. Таким образом, оператор вызова должен быть таким:
c.method("1", 1,"any argument");
Если вы хотите вызвать первый метод только с двумя параметрами, используйте такую реализацию:
public class C {
public void method(String s, Object... o) {
System.out.println("method(String s, Integer i, Object... o)");
}
public void method(Object o, Integer i) {
System.out.println("method(Object o, Integer i)");
}
}
Вы передаете два параметра, поэтому 2-й метод будет рассматриваться компилятором, который имеет 2 аргумента, поскольку количество параметров совпадает со 2-м методом, а затем компилятор проверяет типы данных параметров. Но 1-й ожидаемый параметр для 2-го метода - «Объект», и вы передаете «Строку».
Определение подписи метода основано на трех этапах: первые два этапа основаны на сопоставлении метода без переменных аргументов, а на третьем этапе рассматриваются методы с переменными аргументами.
Method with non var-args will have more priority over method with var-args if both methods seem to be called
// least priority method if both method arguments matching with the calling one
public void method(String s, Integer i, Object... o) {
System.out.println("method(String s, Integer i, Object... o)");
}
public void method(Object o, Integer i) {
System.out.println("method(Object o, Integer i)");
}
Вот технические характеристики:
Шаг 2 во время компиляции: определение подписи метода
- The first phase performs overload resolution without permitting boxing or unboxing conversion, or the use of variable arity method invocation. If no applicable method is found during this phase then processing continues to the second phase.
- The second phase performs overload resolution while allowing boxing and unboxing, but still precludes the use of variable arity method invocation. If no applicable method is found during this phase then processing continues to the third phase.
- The third phase allows overloading to be combined with variable arity methods, boxing, and unboxing.
Согласно правилу 3-й фазы: перегрузку можно сочетать с var-args, т.е. метод с var-args будет иметь меньший приоритет
Вы получаете второй метод, потому что он идеально подходит. Просто передайте еще один параметр
c.method("1", 1, null);, после чего вы сможете выполнить первый метод.