Расширяет ли обертка распаковку? - PullRequest
5 голосов
/ 02 января 2012
class Dec26 {
    public static void main(String[] args) {
        short a1 = 6;
    new Dec26().go(a1);
    new Dec26().go(new Integer(7));
 }
 void go(Short x) { System.out.print("S "); }
 void go(Long x) { System.out.print("L "); }
 void go(int x) { System.out.print("i "); }
 void go(Number n) { System.out.print("N "); }
 }

Вывод:

i N

В приведенном выше примере почему компилятор выбирает параметр расширения (т. Е. Integer -> Number) вместо того, чтобы распаковывать Integer и выбирать параметр int?

Спасибо

Ответы [ 2 ]

6 голосов
/ 02 января 2012

Ваш вопрос не о приоритете преобразований в целом, а о деталях алгоритма разрешения перегрузки.

По причинам обратной совместимости процесс разрешения перегрузки состоит из 3 этапов:

  • Фаза 1: определение подходящих методов арности, применимых к подтипам
    • игнорирует varargs и бокс / распаковку
  • Этап 2. Определение подходящих методов арности, применимых путем преобразования вызова метода
    • игнорирует varargs, но учитывает бокс / распаковку
  • Этап 3: определение применимых методов переменной арности
    • поддерживает все возможные преобразования

Если компилятору не удается определить потенциально применимые методы на одном этапе, он переходит к следующему, чрезмерно анализирует потенциально применимые методы для выбора наиболее конкретного и использует его для вызова.

Как видите, в вашем случае оба вызова применимы подтипом (short является подтипом int, Integer является подтипом Number), поэтому они разрешаются на этапе 1, поэтому тот процесс разрешения перегрузки никогда не достигает фазы 2, и возможная распаковка игнорируется.

См. Также:

0 голосов
/ 02 января 2012

Я думаю, что объект имеет приоритет перед примитивным типом.

...