在Java中重载方法中使用null

时间:2012-10-23 23:51:57

标签: java null overloading

  

可能重复:
  Method Overloading for NULL parameter

以下代码编译并正常运行。

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

的参数的方法

docs说。

  

如果多个成员方法都可访问且适用于a   方法调用,有必要选择一个提供   运行时方法调度的描述符。 Java编程   language使用选择最具体方法的规则。

但是我不明白代码中接受原语int的参数的方法之一被修改为接受包装类型Integer的参数,例如,

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

发出编译时错误。

  

对temp的引用是不明确的,两者都是方法temp(java.lang.String)   methodoverloadingpkg.Main和方法temp(java.lang.Integer)in   methodoverloadingpkg.Main match

在这种特殊情况下,为什么使用原始数据类型重载方法是合法的,但是对于相应的包装类型却不是这样呢?

3 个答案:

答案 0 :(得分:17)

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

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

question.method((String)null)

使用基元类型时,您没有遇到此问题,因为“null”是引用类型,不能与基本类型冲突。但是当你使用引用类型时,“null”可以引用String或Integer(因为null可以转换为任何引用类型)。

请参阅上面评论中发布的the answer in the other question,以获取更多更深入的详细信息,甚至是JLS的一些引用。

答案 1 :(得分:3)

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

Object / Object / String中,编译器的选择很明确: 您将获得int的一个原因String不能int,因此在这种情况下,其相应的方法无法被调用。

但如果您更改null int,编译器将会混淆,因为采用Integer的两种方法都与String的方法一样准确(层次结构中正交)。

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

答案 2 :(得分:2)

首先要了解为什么main.temp(null);解析为temp(String s)而不是temp(Object o)我将原来的回复指向Java method dispatch with null argument。从本质上讲,文字null的类型为nulltypeObject< String< nulltype。因此,null更接近String,然后更接近Object

现在,nullString一样接近Integer,因此当您添加test(Integer)时,它变得模棱两可