Basically, when you have an overloaded method that receives a reference to an object, the JVM chooses the method whose signature contains the most specific object.
In your code example, the JVM chooses the second one one because
String is more specific than Object.
It really works.
Try the following code :
Output is :
A call
B call
C call
C call
A call
It was decided at compile time because you're explicitly passing an argument of type A, even though its reference is of type C
"If someone asks you to do something you don't know how to, don't tell I don't know, tell I can learn instead." - Myself