在Java中,将为null选择哪个重载?

在Java中,将为null选择哪个重载?,java,parameters,methods,invocation,Java,Parameters,Methods,Invocation,如果我用Java写这行代码: JOptionPane.showInputDialog(null, "Write something"); 将调用哪个方法 showInputDialog(组件父级,对象消息) showInputDialog(对象消息,对象初始选择值) 我可以测试一下。但在其他类似的情况下,我想知道会发生什么。在本例中,将调用最具体的方法 showInputDialog(Component parent, Object message) 这通常属于规范(15.12.2)中的

如果我用Java写这行代码:

JOptionPane.showInputDialog(null, "Write something");
将调用哪个方法

  • showInputDialog(组件父级,对象消息)
  • showInputDialog(对象消息,对象初始选择值)
我可以测试一下。但在其他类似的情况下,我想知道会发生什么。

在本例中,将调用最具体的方法

showInputDialog(Component parent, Object message)
这通常属于规范(15.12.2)中的过载解决步骤,尤其是

在不深入了解细节的情况下(您可以在规范中阅读,就像在这里一样),介绍给出了一个很好的总结:

如果多个成员方法同时为 可访问且适用于一种方法 调用时,必须选择 一个用于为 运行时方法调度。爪哇 编程语言使用该规则 最具体的方法是 选择

非正式的直觉就是这样 方法比其他方法更具体 如果由第一个 方法可以传递给另一个 没有编译时类型错误的

都不是。您将收到一个编译器错误,要求您澄清要调用的方法。可以通过显式强制转换第一个参数来执行此操作:

showInputDialog((Object) 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);
  }
}

以上内容将给出一个编译器错误。

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

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

这实际上是一个很好的问题,即使它是人为设计的(您永远不想调用第一个,因为它与
JOptionPane.showInputDialog(“编写东西”);
当方法
f(整数i)
f(字符串s)时调用
f(null)
如何
已定义?两者似乎都不比另一个更具体。@Stephan202:在Eclipse中,我得到了
方法f(整数)类型ExampleClass不明确
这是静态的methods@R.贝姆罗斯:从比尔的回答来看,这也适用于非静态方法。感谢您的测试!这很有意义。整数和字符串都是“相等”的就特殊性而言,Object是这两个类的父类,所以它更模糊。现在,如果删除String方法,将调用Integer方法。@Thomas:没错。看起来这两个不明确的类在继承树的不同分支下有多远都无关紧要,因为String直接扩展Object,而我nteger扩展了数字。@jcasso-我在“doSomething”行上看到一个编译器错误,说“doSomething(String,Object)方法对于类型是不明确的”@CPerkins-是的,jcasso的注释指的是我最初的(不正确的)响应,我说
showInputDialog()
会抛出一个编译器错误,而它不会。
reference to testNullArgument is ambiguous, both method testNullArgument(java.lang.Integer) in testnullargument.Main and method testNullArgument(java.lang.String) in testnullargument.Main match