16

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

在下面的代码中,输出是

细绳

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

目的

我知道当参数类型不完全匹配时方法的重载是如何起作用的,但我不明白如何将null视为一个Object和/或String参数。

对此有何解释?

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);
    }
}
4

5 回答 5

17

它总是根据Java 规范第 15.12.2.5 节使用最具体的方法。

介绍是相当具体的:

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

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

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

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

于 2012-07-24T16:46:59.127 回答
8

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

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

// 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);
    }
}

这是一篇文章的链接,该文章详细讨论了您的代码示例。

于 2012-07-24T16:48:10.093 回答
5

null如果您需要在作为参数传递时强制调用特定的重载方法,则必须对其进行强制转换,如下所示:

m1((String)null);

通过这样做,您可以确保调用正确的重载版本的方法。

于 2012-07-24T16:46:27.123 回答
2

你必须设置类型null来告诉 Java 你想调用什么函数。

所以你这样做:m1((Object) null);Object参数调用实现,然后m1((String) null);调用另一个。

于 2012-07-24T16:46:45.957 回答
1

1.由于String 也是一个对象因此在运行时JVM会混淆调用哪个方法。

2.如果要指定在运行时调用哪个方法,可以通过显式强制转换来实现

例如:

m1((String)null);
于 2012-07-24T16:49:41.577 回答