哪些重载将在Java中被选为null?

如果我用Java编写这行:

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

哪个方法会被调用?

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

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

最具体的方法将被称为 – 在这种情况下

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

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

以上将给出编译器错误。