0

编码

Set<? extends MyClass> mySet = new HashSet<>();
mySet.add(new MyClass());

产生错误信息。原因是编译器不知道mySet 的类型。它只知道mySet的类型是Set<SomeType>,其中SomeTypeMyType 的子类型。 由于编译器不知道 Set<? extends MyClass>指的是它允许插入到该类型集合中的唯一内容是null。

由于这非常令人困惑,并且由于唯一可能元素为null的集合很少使用,因此禁止使用<? extends SomeClass>声明对象时,即如上例所示。这种形式应该用于声明稍后将具体化的抽象(例如参数或泛型类或方法)。

我意识到这不是一个问题,但我想知道对这个想法的反应是什么。

4

2 回答 2

4

我不确定我是否买了它。我可以想象的情况

Set<? extends MyClass> mySet = getOtherSet();

wheregetOtherSet的返回类型可能是Set<MySubClass>,甚至是Set<? extends MyClass>. 也就是说,并且应该是对泛型的合法使用。

将上述合法使用与您描述的有问题的情况区分开来的唯一方法正是 Java 已经做的——它在编译时产生错误消息。

于 2012-04-21T23:36:30.067 回答
0

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.

于 2012-04-22T05:13:11.087 回答