方法重载中奇怪的Java空行为

方法重载中奇怪的Java空行为,java,null,overloading,Java,Null,Overloading,我有以下代码片段: public static void foo(Object x) { System.out.println("Obj"); } public static void foo(String x) { System.out.println("Str"); } 如果我调用foo(null)为什么没有歧义?为什么程序调用foo(字符串x)而不是foo(对象x) 为什么程序调用foo(字符串x)而不是foo(对象x) 这是因为String类扩展自Object,因此对O

我有以下代码片段:

public static void foo(Object x) {
    System.out.println("Obj");
}
public static void foo(String x) {
    System.out.println("Str");
}
如果我调用
foo(null)
为什么没有歧义?为什么程序调用
foo(字符串x)
而不是
foo(对象x)

为什么程序调用
foo(字符串x)
而不是
foo(对象x)

这是因为
String
类扩展自
Object
,因此对
Object
更为具体。所以,编译器决定调用该方法。记住,编译器总是选择最具体的方法来调用。看

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

非正式的直觉是,一种方法比另一种方法更具体 如果可以传递第一个方法处理的任何调用,则另一个 在没有编译时类型错误的情况下打开另一个


但是,如果您有两个参数为-
String
Integer
的方法,那么
null
会出现
歧义
错误,因为编译器无法决定哪一个更具体,因为它们是非协变类型。

当在两种方法中选择参数对两个参数都有效的方法时,编译器将始终选择最具体的参数作为匹配项。在这种情况下,
null
是一个可以作为
对象和
字符串处理的文本<代码>字符串
更为具体,是
对象
的子类,因此编译器使用它。

它正在调用该方法

因为String是Object的一个子类,所以String比Object“更具体”

  • 根据定义,
    null
    的类型是所有其他引用类型的子类型。引用JLS 4.1:

    空引用始终可以进行到任何引用类型的扩展引用转换

  • 调用中涉及的方法签名的解析遵循所有兼容签名集中最特定签名的原则。(JLS 15.12.2.5.选择最具体的方法)

  • 这意味着在您的示例中选择了
    字符串
    重载