Set<? extends AbstractGroup> test;
Это означает, что ваш набор может быть набором любого объекта, который расширяет AbstractGroup
, но обычно компилятор не позволяет вам добавить что-либо к этому набору (так как он не может сказать, например, хотите ли вы добавить * От 1007 * до Set<SubGroupA>
и т. Д.).
test = new HashSet<SubGroupA>()
Ваш фактический набор будет содержать только объекты типа SubGroupA
и их подклассы.
Однако компилятор все равно не знает, каким будет содержимое test
(см. Выше).
Точка подстановочного знака такова: вы можете назначить любой набор переменной, параметризованной с помощью AbstractGroup
или подкласса, таким образом гарантируя, что вы можете привести все объекты , уже находящиеся в , которые сопоставляются с AbstractGroup
(который проверяет компилятор).
Если вы хотите иметь набор, который может содержать любой объект AbstractGroup
, просто не используйте подстановочный знак.
//this would compile (under the assumption that SubGroupA extends AbstractGroup)
Set<? extends AbstractGroup> test = new HashSet<SubGroupA>();
//this wouldn't compile, since the compiler doesn't know the type of test (it might change at runtime etc.)
test.add(new SubGroupA());
//this wouldn't compile since AbstractGroup and SubGroupA are not the exact same type (hence the wildcard would be needed here)
Set<AbstractGroup> test = new HashSet<SubGroupA>();
//this would compile
Set<AbstractGroup> test = new HashSet<AbstractGroup>();
test.add(new SubGroupA());