Обобщения должны точно совпадать, они не проверяются ковариантно / контравариантно, если они явно не объявлены как таковые. Так что Supplier<B>
это не Supplier<A>
, а Supplier<? extends A>
.
Ваша подпись изменится на следующее:
public static <T, I extends T> BiFunctionTest create(BiFunction<Class<? extends T>, Supplier<? extends I>, T> fn) {...
Но теперь для второй проблемы тело вашей функции не является универсальным с точки зрения T
, так как вы используете A.class
и B::new
. Здесь следует использовать общую сигнатуру, если реализация на самом деле не зависит от этих типов A
и B
, но это не так.
Итак, сбросив дженерики из подписи:
public static BiFunctionTest create(BiFunction<Class<? extends A>, Supplier<? extends A>, A> fn) {...
у нас есть соответствующая подпись для тела, которое вы предоставили:
BiFunctionTest o = new BiFunctionTest();
o.a = fn.apply(A.class, B::new);
return o;