Lets suppose I have a ComponentBase
class, who is child of ObjectContextDecorator
and grandchild of ObjectContext
.
public class ComponentBase extends ObjectContextDecorator {
}
public class ObjectContextDecorator extends ObjectContext {
public void set(String objectTypePath, String characteristicName, Object value) {
//...
}
}
public class ObjectContext {
public void set(String characteristicName, Object value, boolean forced) {
//...
}
}
The set
methods on ObjectContextDecorator
and ObjectContext
are very simillar. Consider this sample code:
ComponentBase base = new ComponentBase();
base.set(""OTM4E_EFFLEVEL"", ""IE1 / STD"", true);
Both methods' signatures fit the one being called correctly. I am not able to change the methods' signatures since it is not my code.
How does the compiler know which method I intended to call?
I know that on the IDE you can point out which method you are actually intending to call, but in this situation, I am using a class loader to load a class which has a method containing the sample code.
How does the compiler know which method I intended to call?
It checks for the arguments and determines which one is more specific following the rules described JLS §15.2
In your case, the call:
base.set("OTM4E_EFFLEVEL", "IE1 / STD", true)
the arguments are String
,String
, boolean
Which matches the first class (parameters names changed for brevity)
public class ObjectContext {
public void set(String s, Object o, boolean b){
//...
}
}
The second class is not invoked because the third parameter is an Object
:
public class ObjectContextDecorator extends ObjectContext {
public void set(String s, String ss, Object thisOneRightHere) {
//...
}
}
and while the boolean value true
can match if it is autoboxed still the first one is more specific. The rule that is applying here is:
The first phase (§15.12.2.2) performs overload resolution without permitting boxing or unboxing conversion
But, for instance, if you use the object wrapper Boolean
in the signature:
public class ObjectContext {
public void set(String s, Object o, Boolean b){ //<-- third param changed from boolean to Boolean
//...
}
}
Then they will both match, and the compiler would let you know with the following message:
> A.java:25: error: reference to set is ambiguous
> base.set("OTM4E_EFFLEVEL", "IE1 / STD", true);
> ^ both method set(String,Object,Boolean) in ObjectContext and method set(String,String,Object) in ObjectContextDecorator match
But that's not the case in your example.