package org.study.algos;
public class Study {
public static void main(String[] args) {
A a = new A();
a.m1(null);
}
}
class A {
public v
These methods are "overloaded", not "ambiguous".
According to the Java Language Specification:
When a method is invoked (§15.12), the number of actual arguments (and any explicit type arguments) and the compile-time types of the arguments are used, at compile time, to determine the signature of the method that will be invoked (§15.12.2).
And §15.12.2 says:
There may be more than one such method, in which case the most specific one is chosen.
String
is more specific than Object
, so while null
is compatible with both, the method with the String
parameter is chosen (there are much more complex rules that apply when the parameter types are part of a class or interface hierarchy).
It's a fairly elaborate algorithm, detailed in JLS 15.12. But the part that is relevant here is 15.12.2, which says "the most specific one is chosen." Both the Object and String overloads are "accessible and applicable" (the String is applicable because a null literal is a reference of all types), and the String is more specific.
EDIT: Corrected section, per Syntactic.
I asked a similar question. Jon Skeet wrote a big answer.
The link to my question: Which overload will get selected for null in Java?
null value can be set to reference of any type. All overloaded methods you have are in one inheritance hierarchy Object <- String, the least general one is being choosen. But if you had two overloaded methods that are not in the same hierarchy, then you'd get compilation error about ambigous methods.
A String is an Object, an Object is not a String, thus the first overload is more specific than the second. See JLS 15.12.2, as Syntactic mentioned.