Вопрос-ответ

Which overload will get selected for null in Java?

Какая перегрузка будет выбрана для null в Java?

Если я напишу эту строку на Java:

JOptionPane.showInputDialog(null, "Write something");

Какой метод будет вызван?


  • showInputDialog(Component parent, Object message)

  • showInputDialog(Object message, Object initialSelectionValue)

Я могу это протестировать. Но в других случаях, похожих на этот, я хочу знать, что происходит.

Переведено автоматически
Ответ 1

В этом случае будет вызван наиболее конкретный метод

showInputDialog(Component parent, Object message)

Обычно это относится к "Определить сигнатуру метода" этап разрешения перегрузки в спецификации (15.12.2), и в частности к "Выбору наиболее конкретного метода".

Не вдаваясь в подробности (которые вы можете прочитать так же хорошо в спецификации, как и здесь), введение дает хорошее резюме:


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


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


Ответ 2

В вашем конкретном случае будет вызван более конкретный метод. В целом, однако, есть некоторые случаи, когда сигнатура метода может быть неоднозначной. Рассмотрим следующее:

public class Main {

public static void main(String[] args) {
Main m = new Main();
m.testNullArgument(null);
}

private void testNullArgument( Object o )
{
System.out.println("An Object was passed...");
}

private void testNullArgument( Integer i )
{
System.out.println("An Integer was passed...");
}

private void testNullArgument( String s )
{
System.out.println("A String was passed...");
}
}

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

reference to testNullArgument is ambiguous, both method testNullArgument(java.lang.Integer) in testnullargument.Main and method testNullArgument(java.lang.String) in testnullargument.Main match
Ответ 3

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


showInputDialog((Object) null, "Write something");

или

showInputDialog((Component) null, "Write something");

Обновление Я должен был знать - никогда не сомневайтесь в Джоне Ските. Проблема, о которой я упоминал выше, возникает только тогда, когда невозможно определить, какой метод более специфичен. Вот тестовый пример.:

public class Test {

public void doSomething(String arg1, Object arg2) {
System.out.println("String, Object");
}

public void doSomething(Object arg1, String arg2) {
System.out.println("Object, String");
}

public static void main(String[] args) {
Test test = new Test();
test.doSomething(null, null);
}
}

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

java