Так странно! Пожалуйста, сначала посмотрите код:
public class A {}
public class B extends A {}
public class C extends A {}
public class TestMain {
public <T extends A> void test(T a, T b) {}
public <T extends A> void test(List<T> a, List<T> b) {}
public void test1(List<? extends A> a, List<? extends A> b) {}
public static void main(String[] args) {
new TestMain().test(new B(), new C());
new TestMain().test(new ArrayList<C>(), new ArrayList<C>());
new TestMain().test(new ArrayList<B>(), new ArrayList<C>());
new TestMain().test1(new ArrayList<B>(), new ArrayList<C>());
}
}
Оператор new TestMain().test(new ArrayList<B>(), new ArrayList<C>())
получает ошибку компиляции:
Несоответствие привязки: универсальный метод test (T, T) типа TestMain не применим
за аргументы (ArrayList<B>, ArrayList<C>)
. Предполагаемый тип
ArrayList<? extends A>
не является допустимой заменой ограниченного параметра
<T extends A>
Тем не менее:
new TestMain().test(new B(), new C()) --> compiled ok
new TestMain().test(new ArrayList<C>(), new ArrayList<C>()) --> compiled ok
new TestMain().test1(new ArrayList<B>(), new ArrayList<C>()) --> compiled ok
Если мы определим универсальный перед именем метода, похоже, тип второго универсального параметра List
должен быть таким же, как и у первого. Но нет никаких ограничений, если мы определим generic в параметрах.
Это особенность или ошибка программы компиляции? Есть ли какая-нибудь документация по этому поводу?