Java在返回类型中包含通配符

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (46)

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

情况看起来像这样:

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>

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

提问于
用户回答回答于

有界的通配符具有传染性,这就是你链接的页面似乎感叹。那么,不可否认......但我想我并不认为这是一个大问题。

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

更一般地说,我认为如果你真的希望呼叫站点限制访问对象,那么返回一个有界返回类型是非常合理的。

另一个例子是一个线程安全的队列,你可以交给不同的线程,其中一个线程是生产者,另一个线程是消费者。如果你给制片人一个Queue<? super Foo>,很明显,你打算让他们放入物品(而不是取出物品)。同样,如果你给消费者一个Queue<? extends Foo>,很明显,你打算让他们拿出物品(而不是放入物品)。

用户回答回答于

你可以在类声明中使用有界的类型参数吗?

class EnglishReaderOfPublications<E extends English> { ...

然后你可以在任何你有通配符参数的地方使用这个类型参数。

扫码关注云+社区