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

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

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

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

  • showInputDialog(Component parent, Object message)
  • showInputDialog(Object message, Object initialSelectionValue)

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

3 ответа

Решение

Будет вызван самый специфический метод - в этом случае

showInputDialog(Component parent, Object message)

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

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

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

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

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

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...");
    }
}

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

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

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

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);
  }
}

Выше будет ошибка компилятора.

Другие вопросы по тегам