Passing null to the Overloaded methods [duplicate]

2019-05-23 12:53发布

问题:

This question already has an answer here:

  • Method Overloading for null argument 7 answers

I am confused with the Output of the following two programs.

When I'm only having two methods with parameters as String and Object in Program 1 it gives me output as String.

But when I add a new method with parameter as Integer in Program 2 it won't compile and gives error as The method nullTest(Object) is ambiguous for the type testNull

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

Output : String

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

Output :

Exception in thread "main" java.lang.Error: Unresolved compilation problem:

The method nullTest(Object) is ambiguous for the type testNull

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

And also if I run the program with keeping only Object parameter method, it gives me output as Object.

Can you explain me the reason behind this behavior?

回答1:

When determining which function to use, Java will try to find the function with the most specific input parameter. So in the first case, the String function was chosen as null can be assigned to a String. Object is a parent of String so the String function will be more specific.

In the second case, both Integer and String inherits from Object, and both of these can be assigned to null. Therefore, both of them are equally specific and Java cannot decide which one of these functions to use.



回答2:

The reason is that in case of method overloading,when a parameter is passed that can be referenced by both child and parent class, the method with the parameter of type child class will always be called.

The String is a subclass of Object and therefore its method is called.

In the following example we have class Parent that can be considered as Object class and Child class that can be considered as String class.

Now what happens with your program 1, exactly the same thing happens, that is the method with parameter of child class object gets called

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
{

}

But suppose now you add the following class Child2 that can be considered as your Integer class. Child2 is a subclass of Parent, just like Integer is a subclass of Object

class Child2 extends Parent
{

}

and add the following method

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

Now what happens is exactly what happend in your program 2. The reason is that the compiler is not able to decide which is the right one because of the ambiguity because both are child class of the same same parent class and most importantly none of them(Either Child2 or Child) is a parent of the other.

If we had a case where we have either of the 2 classes a subclass of the other and both inherit Parent class, then there would be no ambiguity and the method with child class will be called.



回答3:

When try to pass the arguments to a method it first try a exact same type. if not then try to have immediate super type. in first program Object is super than string so it match with String. But in second program Object class have two children in same level so java compiler is not able to find which one to be mapped the null value.