5

I have the following 2 methods overloaded in a class :

public class Test{

  public static void main(String []args) throws ParseException{
       Test t = new Test();
      t.testMethod(null);
  }

  public void testMethod(Object o){
    System.out.println("Object");
  }

  public void testMethod(String s){
    System.out.println("String");
  }
}

When I invoke the method testMethod it print "String".

When I add one more overloaded method :

public void testMethod(StringBuilder sb){
    System.out.println("String");
}

It throws me compiler error : The method testMethod is ambigous for type Test..

All this happens when I invoke the method with null

My questions are :

  1. Why it prints String and not Object?
  2. Why is there compilation error on adding third method?
David Rabinowitz
  • 29,904
  • 14
  • 93
  • 125
Abubakkar
  • 15,488
  • 8
  • 55
  • 83
  • Apart from your specific question, I suggest you avoid having one signature with an Object parm and others with some specific data-type. It might be nice to have it as a catch-all, but they're usually lurking traps. – Darius X. Dec 02 '14 at 14:17

3 Answers3

3

Method resolution works by selecting the most specific method that is applicable for the given arguments. In your first case, String is more "specific" than Object (since it is a subclass of Object) and so the String method is chosen.

When you add another method that takes a StringBuilder, both that and the String method are equally "specific" (they are both direct subclasses of Object), so there is an ambiguity as to which should be chosen, hence the error.

arshajii
  • 127,459
  • 24
  • 238
  • 287
1

Why it prints String and not Object?

The java compiler picks the method with the most specific or least generic argument. Since Object is the Superclass of all classes (including String), String class is picked.

Why is there compilation error on adding third method?

Since String and StringBuilder are below Object, the compiler will find the call ambiguous since both String and StringBuilder can accept null, the compiler fails to determine which method to call hence you get error during compilation.

If you try the same thing with IOException and FileNotFoundException instead of String and StringBuilder, you will find out that FileNotFoundException is picked since it is least generic.

TheLostMind
  • 35,966
  • 12
  • 68
  • 104
0

In case1 String inherits from Object, they are in inheritance chain, null matches both, compiler chooses a more specific type - String.

In case 2 String and StringBuilder are not in inheritance chain, compiler cannot choose a more specific type.

Details of overloaded method resolution are described in JLS 15.12.2.

Evgeniy Dorofeev
  • 133,369
  • 30
  • 199
  • 275