Como o Java escolhe qual função sobrecarregada chamar?

Esta é uma questão puramente teórica.

Dadas três classes simples:

class Base {
}

class Sub extends Base {
}    

class SubSub extends Sub {
}

E uma função destinada a operar nessas classes:

public static void doSomething(Base b) {
  System.out.println("BASE CALLED");
}
public static void doSomething(Sub b) {
  System.out.println("SUB CALLED");
}

Parece que o código followign:

SubSub ss = new SubSub();
doSomething(ss);

legitimamente pode resultar na impressão de BASE CHAMADO ou SUB CHAMADO, pois o SubSub pode ser convertido para os dois. De fato, a remoção da sub versão da função faz com que BASE CALLED seja impresso. O que realmente acontece é que "SUB CHAMADO" é impresso. Isso parece significar que a função chamada não depende da ordem em que as funções são definidas, como a versão Base foi chamada primeiro.

O Java apenas olha para todas as diferentes versões da função e escolhe a que requer a menor passagem pela pilha de herança? Isso é padronizado? Está escrito em alguma documentação?

questionAnswers(4)

yourAnswerToTheQuestion