返回类型中的 Java 有界通配符

标签 java generics bounded-wildcard

我读过很多地方,包括 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;
    }
}

总而言之,这是一个我希望能够消费任何英语变体出版物的类(class)。该类需要允许从外部访问发布,但理想情况下,getPublication 的调用者不希望结果作为有界通配符。他们会对 Publication<English> 感到满意.

有办法解决这个问题吗?

最佳答案

有界通配符具有传染性,这就是您链接到的页面似乎在哀叹。好吧,不可否认……但我想我不认为这是一个大问题。

在很多情况下,我会返回一个有界通配符,因为它具有传染性。 JDK,不管是好是坏(我说是坏,但那是一个不同的肥皂盒:))没有只读集合的​​接口(interface)。如果我返回 List<Foo>我不希望人们修改(也许它甚至安全地包装在 Collections.unmodifiableList 中),没有办法在我的返回签名中声明它。作为穷人的解决方法,我会经常返回 List<? extends Foo> .仍然可以尝试通过删除元素或插入 null 来修改该列表,但至少你不能 add(new Foo())作为一个提醒,这个列表可能是只读的。

更一般地说,如果您真的希望调用站点限制对对象的访问,我认为返回具有有限返回类型的东西是完全合理的。

另一个例子是一个线程安全的队列,你将它交给不同的线程,其中一个线程是生产者,另一个是消费者。如果你给生产者一个Queue<? super Foo> ,很明显您希望他们将元素放入其中(而不是取出元素)。同样,如果您给消费者一个 Queue<? extends Foo> ,很明显您想让他们取出元素(而不是放入元素)。

关于返回类型中的 Java 有界通配符,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8966502/

相关文章:

java - 将 fragment 添加到 Activity 中

java - Java 有界通配符泛型的编译器错误

带有泛型的 Java F 绑定(bind)类型

java - 使用 Guice,如何注入(inject)有界通配符类?

java - 如何在没有控制台的情况下运行 java 程序

java - 一个 Controller 中的 Crud 操作是好是坏的 MVC 行为?

具有无意义类型通配符的方法的 Java API 类

java - 为什么这个带有泛型的代码会在 Java 11 中引发 ClassCastException?

java - 循环不变量快速排序

c# - C# 类可以将自己的类型作为泛型类型引用吗?