Как двусмысленность в выборе перегруженных методов, разрешенных на 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
Ответы
Ответ 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.
Ответ 5
Я задал аналогичный вопрос. Джон Скит написал большой ответ.
Ссылка на мой вопрос: Какая перегрузка будет выбрана для null в Java?