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

2022-09-03 17:53:26

我有以下代码片段:

public static void foo(Object x) {
    System.out.println("Obj");
}
public static void foo(String x) {
    System.out.println("Str");
}

如果我打电话,为什么没有歧义?为什么程序调用而不是 ?foo(null)foo(String x)foo(Object x)


答案 1

为什么程序调用而不是foo(String x)foo(Object x)

这是因为类从 扩展,因此更特定于 。因此,编译器决定调用该方法。请记住,编译器始终选择要调用的最具体的方法。参见 JLS 的第 15.12.5 节StringObjectObject

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

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

但是,如果您有两个带有参数 - 和 和 的方法,则会出现 错误,因为编译器无法确定哪一个更具体,因为它们是非协变类型。StringIntegerambiguitynull


答案 2
  1. 根据定义,的类型是所有其他引用类型的子类型。引用JLS 4.1:null

    空引用始终可以进行加宽引用转换为任何引用类型。

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

总而言之,这意味着在您的示例中选择了重载。String