Reputation: 2738
The code
Set<? extends MyClass> mySet = new HashSet<>();
mySet.add(new MyClass());
produces an error message. The reason is that the compiler doesn't know the type of mySet. All it knows is that the type of mySet is Set<SomeType> where SomeType is a subtype of MyType. Since the compiler doesn't know which type Set<? extends MyClass> refers to the only thing it will allow to be inserted into Sets of that type is null.
Since this is very confusing and since there is minimal use for sets whose only possible element is null, it would make more sense to disallow the use of <? extends SomeClass> when declaring objects, i.e., as in the example above. This form should be used only for declaring abstractions (such as parameters or generic classes or methods) that are going to be made concrete later.
I realize this isn't a question, but I wonder what the reaction is to the idea.
Upvotes: 0
Views: 1680
Reputation: 122489
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.
Upvotes: 0
Reputation: 198341
I'm not sure I buy it. I can imagine cases where
Set<? extends MyClass> mySet = getOtherSet();
where getOtherSet
's return type might be Set<MySubClass>
, or even Set<? extends MyClass>
. That is, and should be, a legitimate use of generics.
The only way to distinguish the above legitimate use from the problematic case you describe is exactly what Java already does -- it produces an error message at compile time.
Upvotes: 4