2

I was trying to some examples and was not able to understand the reason for following code error in the following example

public class Test {
public static void print(Integer object){
    System.out.println("object");
}
public static void print(String string){
    System.out.println("String");
}
public static void main(String... args){
    print(null);
}
}

I am getting error as: The method print(Integer) is ambiguous for the type Test

but when I am trying the same example by changing Integer to Object the code compiles fine and gives output as String

public class Test {
public static void print(Object object){
    System.out.println("object");
}
public static void print(String string){
    System.out.println("String");
}
public static void main(String... args){
    print(null);
}
}

Can anyone please help me in understanding why the method with Object in its signature is required when the output is from the method which is having String in it. And what is the reason for the ambiguous type error.

Sumit Surana
  • 1,554
  • 2
  • 14
  • 28

3 Answers3

3

Integer and String are not in same hierarchies. It means you can't assign String into Integer and vice-verse.

but it's not case with Stringand Object because in java every class extends Object class by default.

The Java Language Specification (JLS) in section 15.12 Method Invocation Expressions explains in detail the process that the compiler follows to choose the right method to invoke.

There, you will notice that this is a compile-time task. The JLS says in subsection 15.12.2:

This step uses the name of the method and the types of the argument expressions to locate methods that are both accessible and applicable There may be more than one such method, in which case the most specific one is chosen.

Read more about Java overloading rules

See Method overloading and choosing the most specific type


Look at below sample code where Integer and Number are in same hierarchy that why it's valid.

class Test {
    public  void print(Integer object) {
        System.out.println("object");
    }

    public  void print(Number string) {
        System.out.println("String");
    }
}
new Test().print(null);

enter image description here

Community
  • 1
  • 1
Braj
  • 46,415
  • 5
  • 60
  • 76
  • 2
    Or in short in case of Integer and String as either one of the type is eligible to be 'null' hence the ambiguity is caused but in case of Object and String the ambiguity is there but as String can be labelled a "More Specific" type of "Object" hence as per the Java Spec you mentioned it's the one which gets picked up for execution. Please correct me if I am wrong! – Anirudh Aug 03 '14 at 06:39
3

Null doesn't have a type in Java. When you call print(null), the compiler doesn't know whether you want to call the print(String) function or the print (Integer) function.

The solution is to explicitly cast into the type you want called

print((Integer)null);

or

print((String)null);
Zoltán
  • 21,321
  • 14
  • 93
  • 134
  • The only answer that explained the problem in one sentence and then showed how to fix it. Very helpful. – Gatiivs Jun 21 '22 at 06:52
2

A common practice to disambiguate methods such as this is adding type information into the method name. This has the advantage of making the code explicit and clear, rather than using function overloading to resolve which method is called.

public class Test {
public static void printInteger(Integer object){
    System.out.println("object");
}
public static void printString(String string){
    System.out.println("String");
}
public static void main(String... args){
    printInteger(null);
}
}