Вызов метода перегрузки с параметром null - программирование
Подтвердить что ты не робот

Вызов метода перегрузки с параметром null

Возможный дубликат:
Перегрузка метода для параметра NULL

В приведенном ниже коде результат

Строка

и если я удалю метод с параметром типа String, то выход будет

Объект

Я знаю, как перегрузка методов действует, когда типы параметров не соответствуют точно, но я не могу понять, как null можно рассматривать как параметр Object и/или String.

Каково объяснение этого?

class C {

    static void m1(Object x) {
        System.out.print("Object");
    }
    static void m1(String x) {
        System.out.print("String");
    }

    public static void main(String[] args) {
        m1(null);
    }
}
4b9b3361

Ответ 1

Он всегда использует наиболее специфический метод в соответствии с спецификациями Java, раздел 15.12.2.5.

Вступление достаточно обосновано:

Если более чем один метод-член доступен и применим к вызову метода, необходимо выбрать его для предоставления дескриптора для отправки времени выполнения. Язык программирования Java использует правило, в котором выбран наиболее специфический метод.

Неофициальная интуиция заключается в том, что один метод более конкретный, чем другой, если любой вызов, обработанный первым методом, может быть передан другому, без ошибки типа компиляции.

Вообще говоря, и, по крайней мере, для чтения кода, всегда лучше попытаться быть максимально явным. Вы можете применить null к типу, который соответствует сигнатуре, которую вы хотите вызвать. Но это определенно спорная практика. Предполагается, что все знают это правило и затрудняют чтение кода.

Но это хороший академический вопрос, поэтому я +1 ваш вопрос.

Ответ 2

Когда несколько перегрузок соответствуют сигнатуре, Java выбирает из них наиболее специфический метод.

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

// DOES NOT COMPILE
class C {
    static void m1(Object x) {
        System.out.print("Object");
    }
    static void m1(String x) {
        System.out.print("String");
    }
    static void m1(Integer x) {
        System.out.print("Integer");
    }
    public static void main(String[] args) {
        m1(null);
    }
}

Вот ссылка на сообщение, в котором подробно рассматривается пример кода.

Ответ 3

Если вам нужно принудительно вызвать вызов аппроксимированного перегруженного метода при передаче null в качестве параметра, вы должны выполнить его, например:

m1((String)null);

Выполняя это, вы убедитесь, что вы вызываете правильную перегруженную версию метода.

Ответ 4

Вы должны установить тип null, чтобы сообщить Java, какую функцию вы хотите вызывать.

Итак, вы: m1((Object) null);, чтобы вызвать реализацию с параметром Object, и вы делаете m1((String) null); для вызова другого.

Ответ 5

1. Как String также является объектом, JVM получил confused, чтобы вызвать тот метод в время выполнения.

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

, например:

m1((String)null);