Размножение по сравнению с методом перегрузки

У меня есть 3 метода:

//1 -- check one item
public static <T> void containsAtLeast(String message,
                                       T expectedItem,
                                       Collection<? extends T> found) {
    if (!found.contains(expectedItem))
        Assert.fail("...");        
}

//2 -- check several items
public static <T> void containsAtLeast(String message,
                                       Collection<? extends T> expectedItems,
                                       Collection<T> found) {
    for (T exptetedItem : expectedItems)
        containsAtLeast(message, exptetedItem, found);        
}

//3 -- check several items, without message parameter
public static <T> void containsAtLeast(Collection<? extends T> expectedItems,
                                       Collection<? extends T> found) {
    containsAtLeast(null, expectedItems, found);
}

Я бы ожидал, что метод //3 вызывает //2, но это не так, он вызывает метод //1. Есть ли ошибка в том, что я ожидаю?

* Я использую sdk 1.7.0_25 и Eclipse 4.3 *

Ответы

Ответ 1

Второй метод предполагает, что общий тип expectedItems (? extends T) является подтипом родового типа found (T).

В вашем третьем методе не существует отношения подтипа между двумя типичными типами. Они оба расширяют T, но могут быть братьями и сестрами, например.

Таким образом, второй метод не может быть вызван.

Пример: представьте, что вы вызываете третий метод с этими типами:

containsAtLeast(Collection<Integer> e, Collection<String> f)

Итак, T в вашем третьем методе Object. И ваш первый метод вызывается с помощью T = Object.