Я столкнулся с этим вопросом в викторине,
public class MoneyCalc {
public void method(Object o) {
System.out.println("Object Verion");
}
public void method(String s) {
System.out.println("String Version");
}
public static void main(String args[]) {
MoneyCalc question = new MoneyCalc();
question.method(null);
}
}
Результатом этой программы будет «Версия строки». Но я не мог понять, почему при передаче значения null перегруженному методу выбрана строковая версия. Является ли null переменной String, не указывающей ни на что?
Однако, когда код меняется на,
public class MoneyCalc {
public void method(StringBuffer sb) {
System.out.println("StringBuffer Verion");
}
public void method(String s) {
System.out.println("String Version");
}
public static void main(String args[]) {
MoneyCalc question = new MoneyCalc();
question.method(null);
}
}
он дает ошибку компиляции, говоря: "Метод метода (StringBuffer) неоднозначен для типа MoneyCalc"
java
overloading
zakSyed
источник
источник
Ответы:
Пустую ссылку можно преобразовать в выражение любого типа класса. Так что в случае с
String
этим все в порядке:String
Перегрузки здесь выбран потому , что компилятор Java выбирает наиболее конкретную перегрузку, согласно разделу 15.12.2.5 из JLS . В частности:Во втором случае оба метода все еще применимы, но ни один из них
String
неStringBuffer
является более конкретным, чем другой, поэтому ни один из методов не является более конкретным, чем другой, отсюда и ошибка компилятора.источник
Object
может принимать любой тип и оборачивать его вObject
, тогда как aString
может принимать только aString
. В этом случаеString
это более конкретный тип по сравнению сObject
типом.question.method((String)null)
Кроме того, JLS 3.10.7 также объявляет, что «null» является буквальным значением «нулевого типа». Следовательно, существует тип под названием «null».
Позже JLS 4.1 заявляет, что существует нулевой тип, для которого невозможно объявить переменные, но вы можете использовать его только через нулевой литерал. Позже говорится:
Почему компилятор решил расширить его до String, вполне можно объяснить в ответе Джона .
источник
Вы можете назначить
string
доnull
значения , так что справедливо и порядок для Java и большинство языков программирования подходит к ближайшему типа , а затем к объекту.источник
Чтобы ответить на вопрос в заголовке: не
null
является ни a,String
ни anObject
, но ссылку на любой из них можно присвоитьnull
.Я действительно удивлен, что этот код даже компилируется. Раньше я пробовал нечто подобное, и у меня возникла ошибка компилятора, в которой говорилось, что вызов был неоднозначным.
Однако в этом случае кажется, что компилятор выбирает метод, который находится на самом низком уровне в пищевой цепочке. Предполагается, что вам нужна наименее общая версия метода, которая поможет вам.
Мне нужно будет посмотреть, смогу ли я откопать пример, в котором я получил ошибку компилятора в этом (по-видимому) точно таком же сценарии, хотя ...]
РЕДАКТИРОВАТЬ: Понятно. В сделанной мной версии у меня было два перегруженных метода, принимающих a
String
и anInteger
. В этом сценарии нет «наиболее конкретного» параметра (например,Object
иString
), поэтому он не может выбирать между ними, в отличие от вашего кода.Очень классный вопрос!
источник
Поскольку тип String более конкретен, чем тип объекта. Допустим, вы добавили еще один метод, который принимает целочисленный тип.
Тогда вы получите сообщение об ошибке компилятора, что вызов неоднозначен. Теперь у нас есть два одинаково конкретных метода с одинаковым приоритетом.
источник
Компилятор Java предоставляет наиболее производный тип класса для присвоения null.
Вот пример, чтобы понять это:
вывод: B Class.
с другой стороны:
Результат: метод fun (C) неоднозначен для типа MyTest.
Надеюсь, это поможет лучше разобраться в этом случае.
источник
Источник: https://docs.oracle.com/javase/specs/jls/se8/html/jls-15.html#jls-15.12.2.5
Концепция: наиболее конкретный метод
Объяснение: если доступно более одного метода-члена, и применимо к вызову метода, необходимо выбрать один, чтобы предоставить дескриптор для отправки метода во время выполнения. В языке программирования Java используется правило, согласно которому выбирается наиболее конкретный метод. Попробуйте привести значение null к определенному типу, и нужный вам метод будет вызван автоматически.
источник
Я бы сказал ни то, ни другое. NULL - это состояние, а не значение. Ознакомьтесь с этой ссылкой для получения дополнительной информации об этом (статья относится к SQL, но я думаю, что это также поможет с вашим вопросом).
источник
null
определенно является значением, как определено в JLS.