我在包括here在内的各个地方读过,在方法返回类型中使用有界通配符是一个坏主意。但是,我无法找到一种方法来避免与我的班级。我错过了什么吗?
情况看起来像这样:
class EnglishReaderOfPublications {
private final Publication<? extends English> publication;
EnglishReaderOfPublications(Publication<? extends English> publication) {
this.publication = publication;
}
void readPublication() {
publication.omNomNom();
}
Publication<? extends English> getPublication() {
return publication;
}
}
总之,我希望能够使用任何类型的英语出版物的类。该类需要允许从外部访问该发布,但理想情况下,getPublication
的调用者不希望将结果作为有界通配符。他们会对Publication<English>
感到满意。
有没有办法解决这个问题?
答案 0 :(得分:13)
有界通配符具有传染性,这就是您链接到的页面似乎感叹。嗯,不可否认...但我想我不认为这是一个大问题。
在很多情况下,我将返回一个有界通配符,因为它具有传染性。 JDK,无论好坏(我说更糟糕,但这是一个不同的肥皂盒:))没有只读集合的接口。如果我返回List<Foo>
我不希望人们修改(可能它甚至安全地包裹在Collections.unmodifiableList
中),那么在我的返回签名中无法声明这一点。作为一个穷人的解决方法,我经常会回归List<? extends Foo>
。仍然可以尝试通过删除元素或插入null
来修改该列表,但至少你不能add(new Foo())
提醒这个列表可能是只读的
更一般地说,如果你真的希望调用网站能够限制访问该对象,我认为返回带有有界返回类型的内容是完全合理的。
另一个例子是你交给不同线程的线程安全队列,其中一个线程是生产者而另一个是消费者。如果您给生产者一个Queue<? super Foo>
,很明显您打算将物品放入其中(而不是取出物品)。同样,如果你给消费者一个Queue<? extends Foo>
,很明显你打算把它们拿走(而不是放入物品)。
答案 1 :(得分:5)
你能在类声明中使用有界类型参数吗?
class EnglishReaderOfPublications<E extends English> { ...
然后,您可以在具有通配符参数的任何位置使用此类型参数。
答案 2 :(得分:0)
“理想情况下,getPublication的调用者不希望将结果作为有界通配符。他们会对Publication<English>
感到满意。”
为什么“不会”他们想要它?他们会对Publication<? extends English>
“感到高兴”吗?问题实际上是这些调用者需要对此Publication对象执行的操作。如果他们所做的一切都是从中得到的东西,那么Publication<? extends English>
就足够了,而且它更好,因为它更通用。但是,如果他们需要将内容放入其中,那么您就无法使用Publication<? extends English>
。