Перегрузка метода с помощью примитивов и их оберток

Я пытаюсь сформулировать правила, которые используются в приведенных ниже сценариях. Пожалуйста, объясните, почему я получаю 2 разных результата.

Результат сценария 1: Я - объект.

class Test {

    public static void main (String[] args) {

        Test t = new Test(); 
        byte b_var = 10;
        t.do_the_test(b_var);
    }

    public void do_the_test(Character c) {

       System.out.println("I am a character.");
    }

    public void do_the_test(Integer i) {

      System.out.println("I am an integer.");
    }

    public void do_the_test(Object obj) {

      System.out.println("I am an object.");
    }
}

Результат сценария 2: Я - целое число.

class Test {

    public static void main (String[] args) {

        Test t = new Test(); 
        byte b_var = 10;
        t.do_the_test(b_var);
    }

    public void do_the_test(char c) {

       System.out.println("I am a character.");
    }

    public void do_the_test(int i) {

      System.out.println("I am an integer.");
    }

    public void do_the_test(Object obj) {

      System.out.println("I am an object.");
    }
}

Ответы

Ответ 1

Спецификация Java Language говорит об этом:

Первая фаза (§15.12.2.2) выполняет разрешение перегрузки без разрешения преобразования бокса или распаковки или использования вызова метода переменной arity. Если на этом этапе не обнаружен какой-либо применимый метод, обработка продолжается до второй фазы.

В вашем втором случае сигнатура метода с int применима без автобоксинга, но с расширением числового преобразования. В первом случае для достижения сигнатуры Integer потребуется как расширение преобразования, так и автобоксинг; однако Java делает либо автобоксирование, либо примитивное преобразование, ни тем, ни другое.

Ответ 2

При выборе метода выбираются аргументы, наиболее близкие к переданному параметру.

В первом случае числовое значение имеет выбор из трех классов, которые он не может напрямую отображать. Поскольку Object является супердедом всех классов, он соответствует fn [Object] и, следовательно, Я - объект.

Во втором случае вызов функции обнаружил свою ближайшую совпадающую функцию с fn [integer], там по результату как Я - целое число.