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

2022-09-02 21:52:52

我已经在包括这里在内的各个地方读到过,在方法返回类型中使用有界通配符是一个坏主意。但是,我找不到一种方法来避免我的班级。我错过了什么吗?

情况如下所示:

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;
    }
}

总之,我希望能够使用英语的某种变体中的任何出版物的类。该类需要允许从外部访问发布,但理想情况下,的调用方不希望将结果作为有界通配符。他们会很高兴。getPublicationPublication<English>

有没有办法解决这个问题?


答案 1

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

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

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

另一个示例是线程安全队列,您将该队列传递给不同的线程,其中一个线程是生产者,另一个是使用者。如果你给生产者一个,很明显你打算他们把物品放进去(而不是把物品拿出来)。同样,如果你给消费者一个,很明显你打算他们把物品拿出来(而不是把物品放进去)。Queue<? super Foo>Queue<? extends Foo>


答案 2

是否可以在类声明中使用有界类型参数?

class EnglishReaderOfPublications<E extends English> { ...

然后,您可以在具有通配符参数的任何位置使用此类型参数。


推荐