Вопрос о SCJP: перегрузка метода Java с var-args. Каково объяснение?

Почему следующая программа выдает исключение?

public class MainClass{
  public static void main(String[] argv){
       callMethod(2);
  }
  public static void callMethod(Integer... i){
       System.out.println("Wrapper");
  }
  public static void callMethod(int... i){
       System.out.println("Primitive");
  }

}

Метод callMethod (Целое число []) неоднозначен для типа MainClass

Хорошо, я вижу, что любой из этих двух методов будет работать (если другой будет прокомментирован), но я также знаю, что существует иерархия на том, что происходит, если примитив точно не подобран типом входа метода.

Первая вещь, которую пробуют, состоит в том, чтобы расширить примитив. Так, если был третий метод:

      public static void callMethod(long i){
       System.out.println("long");
      }

Код печатал бы долго

Вторая вещь состоит в том, чтобы упаковать примитив. Таким образом, если бы был метод, берущий Целое число, которое было бы вызванным тем.

Третий приоритет является var-args.

На основе вышеупомянутого приоритета я ожидал бы, что вторые priotity имеют место. Я ожидал бы, что интервал, который будет перенесен в Целое число и (Целое число...), будет вызван. Но конечно этого не происходит. Вместо этого исключение выдается.

Кто-либо видит и может объяснить, почему установление приоритетов не применяется в этом примере?

Удачи!

7
задан Markos Fragkakis 23 February 2010 в 21:18
поделиться

1 ответ

Вы правы в том, что расширение предшествует упаковке, которая, в свою очередь, предшествует аргументам var-args.

Но вы, кажется, обрабатываете первый метод как callMethod (Integer i) , а не callMethod (Integer ... i) . Поскольку оба метода используют аргументы var-args, существует приоритет привязка . То есть ни один из них не соответствует критериям для бокса в одиночку, но оба соответствуют критериям для var-args.

Помните, что нельзя расширять, а затем вставлять в коробку (хотя я провел некоторое исследование, прежде чем опубликовать этот ответ, и обнаружил, что коробку, а затем расширение - законно). Точно так же вы не получите поведение box, затем var-args; компилятор переходит сразу к шагу var-args и видит два метода, которые принимают var-args.

РЕДАКТИРОВАТЬ: Я должен уточнить, что вы получите поведение box-then-var-args, если нет двусмысленности. Другими словами, если существует только один callMethod () , и он принимает Integer ... i , вы получите « Wrapper ».

9
ответ дан 7 December 2019 в 03:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: