(...), но когда мы используем какой-либо объект класса Wrapper, используется, скажем, предположим, что Integer, например, следующий
Integer i = new Integer(10)
System.out.println(i);
это toString () отвечает за его печать или распаковку?
Вы передаете Object
в println
, поэтому, очевидно, вызывается println(Object obj)
, который записывает вывод String.valueOf(obj)
который вызывает obj.toString()
, если obj
не null
.
PS: Без обид, но почему бы вам не взглянуть на источники?
Обновление: Возможно, я упустил суть вопроса (которыйвводить в заблуждение в его нынешнем виде, если я могу).На самом деле, вопрос может быть следующим:
(...), но когда мы используем любой тип объектов класса Wrapper, скажем, предположим, что Integer, например, следующий
Integer i = new Integer(10)
System.out.println(i);
Какой метод будетбыть названным: println(Object)
или println(int)
?
Если это то, о чем идет речь, то ответ, конечно, лежит в Спецификация языка Java .Для упрощения, метод, вызываемый во время выполнения, будет методом, который определяется во время компиляции.Теперь, как компилятор определяет метод, который будет вызван?Ну, это объясняется в разделе 15.12 Выражения вызова метода .Я не буду описывать все детали, спецификация делает это лучше, чем я, но, в основном, первый шаг - найти класс или интерфейс для поиска, второй шаг - найти все применимые методы, а затем подобрать наиболее конкретный.метод, третий шаг - проверить, подходит ли выбранный метод.Я сосредоточусь на втором шаге (который интересный здесь).Как подробно описано в разделе 15.12.2. Время компиляции. Шаг 2. Определение сигнатуры метода :
Метод применим, если он применим либо путем подтипа (§15.12.2.2) , применимый путем преобразования вызова метода (§15.12.2.3) , или это применимый метод переменной арности (§15.12.2.4) .
Процесс определения применимости начинается с определения потенциально применимых методов (§15.12.2.1) .Оставшаяся часть процесса разбита на три этапа.
Обсуждение
Цель разделения на этапы - обеспечить совместимость со старыми версиями Java.язык программирования.
Первая фаза (§15.12.2.2) выполняет разрешение перегрузки без разрешения преобразования в бокс или распаковку или использования вызова метода переменной arity.Если на этом этапе не найдено подходящего метода, тогда обработка переходит ко второму этапу.
Обсуждение
Это гарантирует, что любые вызовы, которые были действительны в более старых версияхязыка не считаются неоднозначными в результате введения методов переменной арности, неявного бокса и / или распаковки.
Второй этап (§15.12.2.3) выполняетразрешение перегрузки, позволяя упаковывать и распаковывать, но все же исключает использование вызова метода переменной арности.Если на этом этапе не найдено подходящего метода, то обработка продолжается до третьего этапа.
Обсуждение
Это гарантирует, что метод переменной арности никогда не будет вызываться, еслисуществует применимый метод фиксированной арности.
Третий этап (§15.12.2.4) позволяет комбинировать перегрузку с методами переменной арности, упаковки и распаковки.
Решение о том, применим ли метод, в случае универсальных методов (§8.4.4) потребует определения фактических аргументов типа.Фактические аргументы типа могут передаваться явно или неявно.Если они передаются неявно, они должны быть выведены (§15.12.2.7) из типов выражений аргумента.
Iе несколько применимых методов имеют
был идентифицирован во время одного из
три этапа тестирования применимости,
тогда выбирается самый конкретный,
как указано в разделе §15.12.2.5 .
Смотрите следующие подразделы для
подробности.
В этом конкретном случае println(Obj)
применимо подтипом (а println(int)
будет применимо при преобразовании вызова, так как упаковка / распаковка является преобразованием (§5.3) ). Таким образом, компилятор войдет в фазу 1 . И если мы посмотрим на последнее предложение:
Если метод, применимый к подтипу, не найден, поиск применимых методов продолжается с фазы 2 (§15.12.2.3) . В противном случае самый специфический метод (§15.12.2.5) выбирается среди методов, которые применимы, путем подтипа .
Здесь нет никаких других методов, применимых к подтипам, так что это конец, будет вызван println(Object)
(и, таким образом, будет вызван toString()
, чтобы ответить на первоначальный вопрос).