This question already has an answer here:
I have the following code snippet:
public static void foo(Object x) {
System.out.println("Obj");
}
public static void foo(String x) {
System.out.println("Str");
}
If I call foo(null)
why is there no ambiguity? Why does the program call foo(String x)
instead of foo(Object x)
?
When given a choice between two methods where the argument is valid for both parameters, the compiler will always choose the most specific parameter as a match. In this case,
null
is a literal that can be handled as anObject
and aString
.String
is more specific and a subclass ofObject
so the compiler uses it.The type of
null
is by definition a subtype of every other reference type. Quote JLS 4.1:The resolution of the method signature involved in an invocation follows the principle of the most specific signature in the set of all compatible signatures. (JLS 15.12.2.5. Choosing the Most Specific Method).
Taken together this means that the
String
overload is chosen in your example.That is because
String
class extends fromObject
and hence is more specific toObject
. So, compiler decides to invoke that method. Remember, Compiler always chooses the most specific method to invoke. See Section 15.12.5 of JLSHowever, if you have two methods with parameter -
String
, andInteger
, then you would getambiguity
error fornull
, as compiler cannot decide which one is more specific, as they are non-covariant types.It's calling the most specific method.
Since String is a subclass of Object, String is "more specific" than Object.