53

如果我用 Java 编写这一行:

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

将调用哪个方法?

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

我可以测试一下。但在其他类似的情况下,我想知道会发生什么。

4

3 回答 3

64

将调用最具体的方法 - 在这种情况下

showInputDialog(Component parent, Object message)

这通常属于规范(15.12.2)中重载解析的“确定方法签名”步骤,特别是“选择最具体的方法”

在不深入细节的情况下(您可以在此处阅读规范中的内容),引言给出了一个很好的总结:

如果多个成员方法既可访问又适用于方法调用,则有必要选择一个为运行时方法分派提供描述符。Java 编程语言使用选择最具体方法的规则。

非正式的直觉是,如果第一个方法处理的任何调用可以传递给另一个方法而不会出现编译时类型错误,那么一个方法比另一个方法更具体。

于 2009-10-09T18:59:33.087 回答
13

在您的特定情况下,将调用更具体的方法。但是,一般来说,在某些情况下方法签名可能不明确。考虑以下:

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
于 2009-10-09T19:10:14.893 回答
9

两者都不。您将收到一个编译器错误,要求您澄清要调用的方法。您可以通过显式转换第一个参数来做到这一点:

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

或者

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

更新我应该知道 - 永远不要怀疑 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);
  }
}

以上将给出编译器错误。

于 2009-10-09T18:59:53.133 回答