Какая перегрузка будет выбрана для 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...");
    }
}

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

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

Забастовкa >

Обновить Я должен был знать - никогда не сомневаюсь в Jon Skeet. Проблема, о которой я говорил выше, возникает только тогда, когда невозможно определить, какой из методов более конкретный. Здесь тестовый пример:

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

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