Подтвердить что ты не робот

Как двусмысленность в выборе перегруженных методов, разрешенных на Java?

package org.study.algos;
public class Study {

    public static void main(String[] args) {
       A a = new A();
       a.m1(null);
    }
 }
 class A {
    public void m1(String s) {
       System.out.println("String");
        System.out.println(s);
    }
    public void m1(Object obj) {
       System.out.println("Object");
       System.out.println(obj);
    }
}

Здесь вывод

Строка нуль

Почему JVM разрешает метод одному с аргументом String?

Спасибо заранее J

4b9b3361

Ответ 1

Это довольно сложный алгоритм, подробно описанный в JLS 15.12. Но здесь важна роль 15.12.2, в которой говорится, что выбран "наиболее конкретный". Перегрузки объектов и строк являются "доступными и применимыми" (строка применима, поскольку нулевой литерал является ссылкой всех типов), а строка более конкретна.

РЕДАКТИРОВАТЬ: Исправлена ​​секция в синтаксисе.

Ответ 2

Эти методы "перегружены", а не "неоднозначны".

В соответствии с Спецификация языка Java:

При вызове метода (§15.12) количество фактических аргументов (и любых явные аргументы типа) и типы аргументов компиляции используются во время компиляции для определить подпись метода который будет вызываться (§15.12.2).

И в §15.12.2 говорится:

Может быть более одного такого метод, в этом случае наиболее конкретный.

String более специфичен, чем Object, поэтому, пока null совместим с обоими, выбирается метод с параметром String (существуют гораздо более сложные правила, которые применяются, когда типы параметров являются частью иерархию классов или интерфейсов).

Ответ 3

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

Ответ 4

Строка - это объект, объект не является строкой, поэтому первая перегрузка более конкретная, чем вторая. См. JLS 15.12.2, как упоминалось в Syntactic.