Как компилятор узнает, какой метод я намеревался вызвать?
Он проверяет аргументы и определяет, какой из них является более точным c, следуя описанным правилам JLS §15.2
В вашем случае, вызов:
base.set("OTM4E_EFFLEVEL", "IE1 / STD", true)
аргументы String
, String
, boolean
Что соответствует первый класс ( имена параметров изменены для краткости )
public class ObjectContext {
public void set(String s, Object o, boolean b){
//...
}
}
Второй класс не вызван, потому что третий параметр Object
:
public class ObjectContextDecorator extends ObjectContext {
public void set(String s, String ss, Object thisOneRightHere) {
//...
}
}
, и, хотя логическое значение true
может совпадать, если оно автоматически занесено в коробку, первое значение будет более точным c. Здесь применяется следующее правило:
На первом этапе (§15.12.2.2) выполняется разрешение перегрузки без , разрешающее преобразование в бокс или распаковку
Но, например, если вы используете обертку объекта Boolean
в подписи:
public class ObjectContext {
public void set(String s, Object o, Boolean b){ //<-- third param changed from boolean to Boolean
//...
}
}
Тогда они оба будут совпадать, и компилятор сообщит вам следующее сообщение :
> 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
Но это не так в вашем примере.