Set<? extends MyClass>
is a perfectly useful type in general. You can have a method argument that is Set<? extends MyClass>
, that allows you to call it with Set<OneClass>
or Set<AnotherClass>
. If all the method needs to do is get MyClass
elements out of it, it's fine. Or, you can have a statement like
Set<? extends MyClass> mySet = someObject.someMethod();
where the method could return sets of different types (some instances might return Set<OneClass>
, while others might return Set<AnotherClass>
), and all you need to do with it now is get MyClass
things out of it.
The example you are showing specifically deals with initializing Set<? extends MyClass>
with a new empty set. I agree that this case is not that useful. However, if we need to make a rule to disallow this case, it would have to make assigning an object creation expression different from assigning other expressions (like a method call), even if they are equivalent (the method call could also be just returning a new empty set). I think that it would be unreasonable to explicitly exclude such a case when it does not do any harm. You could similarly argue that being able to create arrays of length 0 is a pretty useless, and should be disallowed; however, it makes the language more general to be able to handle edge cases.