Попробуйте:
public List<Foo> getFoos() {
List<Foo> foos = new ArrayList<Foo>();
foos.add(new SubFoo());
return foos;
}
Общий конструктор ArrayList должен иметь определенный тип для параметризации, вы не можете использовать '?' подстановочный знак там. Изменение экземпляра на «новый ArrayList ()» решит первую ошибку компиляции.
Объявление переменной 'foos' может иметь подстановочные знаки, но, поскольку вы знаете точный тип, имеет больше смысла ссылаться на ту же информацию о типе. То, что у вас сейчас есть, говорит о том, что foos содержит какой-то определенный подтип Foo, но мы не знаем, какой именно. Добавление SubFoo может быть запрещено, поскольку SubFoo не является «всеми подтипами Foo». Изменение объявления на «List foos =» устраняет вторую ошибку компиляции.
Наконец, я бы изменил тип возвращаемого значения на «List », поскольку клиенты этого метода не смогут многое сделать с возвращаемым значением, как определено в настоящее время. Вы должны редко использовать подстановочные знаки в возвращаемых типах. При необходимости используйте параметризованную сигнатуру метода, но предпочитайте, чтобы ограниченные типы появлялись только в аргументах метода, так как это оставляет вызывающей стороне, которая может передавать определенные типы и работать с ними соответственно.