10

The following code prints "String"

public class Riddle {

    public static void main(String[] args) {
        hello(null);
    }

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


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

}

Why does that code compile? Isn't null ambiguous?

For example, the following code will NOT compile because of an ambiguous signature.

public class Riddle {

    public static void main(String[] args) {
        hello(null);
    }

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

    public static void hello(Integer o) {
        System.out.println("Integer");
    }

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

}

Can someone please explain why the first example can compile without having ambiguous errors?

Jonathan Beaudoin
  • 2,158
  • 4
  • 27
  • 63
  • 3
    The `null` is just a parameter. In the second case, the `Object` method signature cannot be resolved against the other two. โ€“ Tim Biegeleisen Mar 23 '16 at 23:37
  • 2
    Congratulations, I think you've found one of the actual holes in Java's Type Theory. In general, "Null" is kind of a weird creature to type systems. If you're interested in this, you might check out the Option type that some languages use... I personally think it's a really good feature, and wish it weren't too late to bring it into Java. โ€“ Edward Peters Mar 23 '16 at 23:38
  • 5
    See also http://stackoverflow.com/questions/2608394/how-is-ambiguity-in-selecting-from-overloaded-methods-resolved-in-java or also http://stackoverflow.com/questions/1545501/which-overload-will-get-selected-for-null-in-java โ€“ Philipp Mar 23 '16 at 23:42

2 Answers2

1

In the second case doesn't compile as the compiler can't decide between the method that takes an Integer and the method that takes a String, where as in case of first the compiler can figure it out.

Reference : http://docs.oracle.com/javase/specs/jls/se7/html/jls-15.html#jls-15.12.2

Rishi
  • 1,163
  • 7
  • 12
0

please, see JLS ยง15.12.2

following order of method resolving for calling purpose is important when same type data-type is there,

  1. (for primitive data-type)exact data-type match then call it. 1.1 if not then call to broader then this data-type available then call it.
  2. match for Wrapper type of Data-type or parent of it if above failed then.
  3. Vararg of this data-type will match if above 2-failed.
Vishal Gajera
  • 4,137
  • 5
  • 28
  • 55