Какая перегрузка будет выбрана для NULL в Java? - PullRequest
52 голосов
/ 09 октября 2009

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

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

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

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

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

Ответы [ 3 ]

62 голосов
/ 09 октября 2009

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

showInputDialog(Component parent, Object message)

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

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

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

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

12 голосов
/ 09 октября 2009

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

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
9 голосов
/ 09 октября 2009

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

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

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

...