使用参数 null 的重载方法调用

2022-09-03 04:45:43

可能的重复:
NULL 参数的方法重载

在下面的代码中,输出是

字符串

如果我删除带有类型参数的方法,则输出是String

对象

我知道当参数类型不完全匹配时,方法的重载是如何起作用的,但我无法理解如何将null视为和/或参数。ObjectString

这是什么原因呢?

class C {

    static void m1(Object x) {
        System.out.print("Object");
    }
    static void m1(String x) {
        System.out.print("String");
    }

    public static void main(String[] args) {
        m1(null);
    }
}

答案 1

它始终根据 Java 规范 15.12.2.5 节使用最具体的方法。

介绍是相当具体的:

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

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

一般来说,至少对于代码的可读性,最好尝试尽可能明确。您可以将 您转换为与要调用的签名匹配的类型。但这绝对是一个值得怀疑的做法。它假设每个人都知道这个规则,并使代码更难阅读。null

但这是一个很好的学术问题,所以我+1你的问题。


答案 2

当多个重载与一个签名匹配时,Java 会从中选择最具体的方法。

的值同时匹配 和 ,但是是 的子类,因此被选取。如果在类层次结构中添加另一个具有 同级的重载,则会出现编译错误。\nullObjectStringStringObjectStringString

// DOES NOT COMPILE
class C {
    static void m1(Object x) {
        System.out.print("Object");
    }
    static void m1(String x) {
        System.out.print("String");
    }
    static void m1(Integer x) {
        System.out.print("Integer");
    }
    public static void main(String[] args) {
        m1(null);
    }
}

下面是一个帖子的链接,该帖子在某种程度上讨论了您的代码示例。