Overload resolution, which method is called

It's all explained in the JLS §15.2 Method Invocation Expressions. It tells you all about how the correct method to call is chosen. And note that this does not always succeed.

In your specific case, the two methods are overloads of each other, so §15.2.2 "Compile-Time Step 2: Determine Method Signature" applies - which overload to call is determined at compile time. This step is further split into 3 phases.

The first phase (§15.12.2.2) performs overload resolution without permitting boxing or unboxing conversion, or the use of variable arity method invocation. If no applicable method is found during this phase then processing continues to the second phase.

In the first phase, the compiler tries to find applicable methods without allowing boxing conversions. In your case, to call the overload that takes an Object, a boxing conversion is needed to convert the boolean true to the type Object, so that overload won't be chosen in the first phase.

If no method applicable by strict invocation is found, the search for applicable methods continues with phase 2 (§15.12.2.3).

Otherwise, the most specific method (§15.12.2.5) is chosen among the methods that are applicable by strict invocation.

Well, we have found exactly one method, so we will just choose that method. There is no ambiguity.


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.