Выбор метода перегрузки

Рассмотрим пример

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, но мне это не интуитивно понятно.

Вы получаете второй метод, потому что он идеально подходит. Просто передайте еще один параметр c.method("1", 1, null);, после чего вы сможете выполнить первый метод.

Sudhir Ojha 22.04.2019 07:40
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
1
1
87
5
Перейти к ответу Данный вопрос помечен как решенный

Ответы 5

Это потому, что вы отправили только два аргумента, поэтому будет выполнен метод с двумя параметрами, отправьте три и будет выполнен метод с тремя параметрами.

Сначала вам нужно будет понять одну из объектно-ориентированных концепций (и ее синтаксис 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 во время компиляции: определение подписи метода

  1. 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.
  2. 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.
  3. The third phase allows overloading to be combined with variable arity methods, boxing, and unboxing.

Согласно правилу 3-й фазы: перегрузку можно сочетать с var-args, т.е. метод с var-args будет иметь меньший приоритет

Другие вопросы по теме