Проблема вызвана использованием ? extends V
с List
в doSomething
определении метода, но когда вы вызываете метод, вы используете new Foo<List<Object>>
напрямую.
Там, List<? extends Object>
- этоне равно List<Object>
, так как ? extends Object
является ковариацией с типом Object
, например, вы не можете поместить элемент типа Object
в List<? extends Object>
, потому что компилятор не может вывести, чтотип должен быть ? extends Object
.
Так что для вашего примера вы можете попытаться исправить это, используя new Foo<List<? extends Object>>()
, например, как:
doSomething(() -> new Foo<List<? extends Object>>() {
@Override
public List<Object> getBar() {
return null;
}
});
И для чего используйте анонимный класс может работать здесь, попробуйте декомпилировать анонимный класс ,
class Main$1$1 implements Foo<java.util.List<java.lang.Object>>
...
final class Main$1 implements SupplierT<java.util.List<java.lang.Object>> {
...
, как вы можете видеть, он переопределяет ? extends V
как Object
тип.
но для лямбды он не сгенерирует соответствующий анонимный класс, например:
class Main$1 implements SupplierT<java.util.List<java.lang.Object>>
вышеупомянутый анонимный класс не сгенерирует, а lambda будет использовать invokedynamic
вызов инструкции непосредственно, как:
0: invokedynamic #5, 0 // InvokeDynamic #0:get:()LSupplierT;
Так что все равно попытайтесь вывести ? extends V
, это приведет к компиляции файловls .
Ссылка:
https://docs.oracle.com/javase/tutorial/java/generics/subtyping.html
или этот пример:
Is Подкласс List?Почему дженерики Java не являются неявно полиморфными?