将null传递给重载方法

时间:2016-04-24 10:48:28

标签: java object null integer

我对以下两个程序的输出感到困惑。

当我在程序1中只有两个参数为StringObject的方法时,它会将输出设为String

但是当我在程序2中添加一个参数为Integer的新方法时,它不会编译并给出错误 对于类型testNull

,nullTest(Object)方法不明确

计划1:

package onkartest;

public class TestNull {
    public static void nullTest(Object b)
    {
        System.out.println("object");
    }       

    public static void nullTest(String x)
    {
        System.out.println("String");
    }

    public static void main(String x[])
    {           
        nullTest(null);         
    }
}

输出:字符串

计划2:

package onkartest;

public class TestNull {
    public static void nullTest(Object b)
    {
        System.out.println("object");
    }       

    public static void nullTest(String x)
    {
        System.out.println("String");
    }

    public static void nullTest(Integer i)
    {
        System.out.println("Integer ");
    }

    public static void main(String x[])
    {       
        nullTest(null);     
    }
}

输出:

  

线程中的异常" main" java.lang.Error:未解决的编译问题:

     

对于类型testNull

,nullTest(Object)方法不明确      

在onkartest.testNull.main(testNull.java:26)

如果我只使用Object参数方法运行程序,它会将输出设为Object

你能解释一下这种行为背后的原因吗?

3 个答案:

答案 0 :(得分:2)

在确定使用哪个函数时,Java将尝试使用最具体的输入参数查找函数。所以在第一种情况下,选择String函数为null可以赋给String。 Object是String的父级,因此String函数将更具体。

在第二种情况下,Integer和String都继承自Object,并且这两者都可以赋值为null。因此,它们都是同样具体的,Java无法决定使用这些函数中的哪一个。

答案 1 :(得分:2)

原因是在方法重载的情况下,当传递一个可以被子类和父类引用的参数时,将始终调用带有子类类型参数的方法。

String是Object的子类,因此调用其方法。

在以下示例中,我们将类Parent视为Object类和Child类,可以将其视为String类。

现在你的程序1发生了什么,完全相同的事情发生了,那就是带有子类对象参数的方法被调用

public class Program 
{
 public static void method(Parent p1)//Consider the Parent as Object 
 {
     System.out.println("parent");   
 }
 public static void method(Child c)//Consider the Child as String
 {
     System.out.println("Child");    
 } 
 public static void main(String []args)
 {
     method(null);
 }     
}
class Parent//consider Parent as Object
{

}
class Child extends Parent//consider Child as String
{

}

但是现在假设您添加了以下可以被视为Child2类的类IntegerChild2Parent的子类,就像IntegerObject

的子类一样
class Child2 extends Parent
{

}

并添加以下方法

public static void method(Child2 c)//Consider the Child2 as Integer 
 {
     System.out.println("Child");    
 } 

现在发生的事情正是程序中发生的事情2.原因是编译器无法确定哪一个是正确的,因为它们都是同一个父类的子类,而且最重要的是,没有一个(Child2或Child)是另一个的父母

如果我们有一个案例,我们将2个类中的任何一个作为另一个类的子类并且都继承了父类,那么就没有歧义,并且将调用带有子类的方法。

答案 2 :(得分:1)

当尝试将参数传递给方法时,首先尝试完全相同的类型。如果没有,那么尝试立即超级类型。在第一个程序中,Object超出字符串,因此它与String匹配。但是在第二个程序中,Object类有两个相同级别的子级,因此java编译器无法找到哪个要映射的空值。