6

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

以下代码编译并运行良好。

public class Main
{
    public void temp(Object o)
    {
        System.out.println("The method with the receiving parameter of type Object has been invoked.");
    }

    public void temp(String s)
    {
        System.out.println("The method with the receiving parameter of type String has been invoked.");
    }

    public void temp(int i)
    {
        System.out.println("The method with the receiving parameter of type int has been invoked.");
    }

    public static void main(String[] args)
    {
        Main main=new Main();
        main.temp(null);
    }
}

在这段代码中,要调用的方法是接受类型参数的方法String

文档说。

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

但我不明白何时int修改代码中接受基元参数的方法之一以接受包装器类型的参数,Integer例如,

public void temp(Integer i)
{
    System.out.println("The method with the receiving parameter of type Integer has been invoked.");
}

发出编译时错误。

对 temp 的引用不明确,methodoverloadingpkg.Main 中的方法 temp(java.lang.String) 和 methodoverloadingpkg.Main 中的方法 temp(java.lang.Integer) 都匹配

在这种特殊情况下,为什么重载具有原始数据类型的方法是合法的,但其相应的包装器类型似乎并非如此?

4

3 回答 3

18

如果你被问到什么是更专业的“字符串”或“对象”,你会说什么?显然是“字符串”,对吧?

如果有人问你:什么是更专业的“字符串”或“整数”?没有答案,它们都是对象的正交特化,你如何在它们之间进行选择?然后你必须明确你想要哪一个。例如通过转换你的空引用:

question.method((String)null)

当您使用原始类型时,您不会遇到这个问题,因为“null”是一个引用类型并且不能与原始类型冲突。但是当您使用引用类型时,“null”可以引用 String 或 Integer(因为 null 可以转换为任何引用类型)。

请参阅我在上面的评论中发布的另一个问题的答案,以获取更多和更深入的细节,甚至是 JLS 的一些引用。

于 2012-10-23T23:57:48.260 回答
3

如果您null作为重载方法的参数传递,则选择的方法是具有最专业类型的方法,因此在这种情况下:String被选择而不是最宽容的:Object

Object//其中,编译Stringint的选择是明确的:你会得到String's one cause an intcannot be null,因此在这种情况下,它对应的方法没有资格被调用。

但是,如果您更改intfor Integer,编译器会感到困惑,因为采用的两种方法String都与 's 一样准确Integer(层次结构正交)。

并且编译器不能(不想要?^^)随机选择。

于 2012-10-23T23:57:53.857 回答
2

首先要了解为什么main.temp(null);解析为temp(String s)而不是temp(Object o)我指出我对Java method dispatch with null argument的旧回复。本质上,文字null是类型nulltypeObject< String< nulltype。所以null更接近String然后它是Object

现在 ,和一样null接近, 所以当你添加它时会变得模棱两可StringIntegertest(Integer)

于 2012-10-24T00:04:20.847 回答