Перегрузка метода Java - Общие параметры и параметры в одном и том же дереве наследования

Давайте предположим, что у меня есть следующий код:

// Method acception generic parameter
public static <T> T foo(T para) {
    return para;
}

// Method accepting Integer parameter
public static Integer foo(Integer para) {
    return para + 1;
}

// Method accepting Number parameter
public static Number foo(Number para) {
    return para.intValue() + 2;
}

public static void main(String[] args) {
    Float f = new Float(1.0f);
    Integer i = new Integer(1);
    Number n = new Integer(1);
    String s = "Test";

    Number fooedFloat = foo(f);     // Uses foo(Number para)
    Number fooedInteger = foo(i);   // Uses foo(Integer para)
    Number fooedNumber = foo(n);    // Uses foo(Number para)
    String fooedString = foo(s);    // Uses foo(T para)

    System.out.println("foo(f): " + fooedFloat);
    System.out.println("foo(i): " + fooedInteger);
    System.out.println("foo(n): " + fooedNumber);
    System.out.println("foo(s): " + fooedString);
}

Вывод выглядит следующим образом:

foo(f): 3
foo(i): 2
foo(n): 3
foo(s): Test

Теперь вопрос (ы):

foo(n) звонкиfoo(Number para)скорее всего потому чтоn определяется какNumberхотя у него естьInteger назначен на это. Так что я прав в предположении, что решение о том, какой из перегруженных методов принимается, происходит во время компиляции без динамического связывания? (Вопрос остатический а такжединамический связывание)foo(f) использованияfoo(Number para), в то время какfoo(i) использованияfoo(Integer para), Толькоfoo(s) использует общую версию. Таким образом, компилятор всегда смотрит, есть ли не универсальная реализация для данных типов, и только если нет, он возвращается к универсальной версии? (Вопрос одженерики)Снова,foo(f) использованияfoo(Number para), в то время какfoo(i) использованияfoo(Integer para), Еще,Integer i также будетNumber, Таким образом, всегда используется метод с «самым внешним» типом в дереве наследования? (Вопрос онаследование)

Я знаю, что это много вопросов, и пример не взят из производительного кода, но я просто хотел бы знать, что «происходит позади» и почему что-то происходит.

Также очень ценятся любые ссылки на документацию по Java или спецификацию Java, я сам не смог их найти.

Ответы на вопрос(3)

Ваш ответ на вопрос