简体   繁体   English

Java在返回类型中绑定了通配符

[英]Java bounded wildcard in return type

I've read in various places including here that having a bounded wildcard in a method return type is a bad idea. 我已经阅读过各种各样的地方,包括方法返回类型中使用有界通配符是一个坏主意。 However, I can't find a way to avoid it with my class. 但是,我无法找到一种方法来避免与我的班级。 Am I missing something? 我错过了什么吗?

The situation looks something like this: 情况看起来像这样:

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

In summary, a class that I want to be able to consume any publication that is in some variant to English. 总之,我希望能够使用某些版本的英语版本的类。 The class needs to allow access to the publication from outside but, ideally, the callers of getPublication wouldn't want the result as a bounded wildcard. 该类需要允许从外部访问该发布,但理想情况下, getPublication的调用者不希望将结果作为有界通配符。 They would be happy with Publication<English> . 他们会对Publication<English>感到满意。

Is there a way round this? 这有什么方法吗?

Bounded wildcards are contagious, which is what the page you link to seems to lament. 有界的通配符具有传染性,这就是你链接到的页面似乎感叹。 Well, there's no denying that... but I guess I don't see it as such a big problem. 嗯,不可否认...但我想我不认为这是一个大问题。

There are many cases where I return a bounded wildcard exactly because it's contagious. 在很多情况下我会返回一个有界的通配符, 因为它具有传染性。 The JDK, for better or worse (I say for worse, but that's a different soap box :) ) doesn't have interfaces for read-only collections. JDK,无论好坏(我说更糟糕,但这是一个不同的肥皂盒:))没有只读集合的​​接口。 If I return a List<Foo> that I don't want people modifying (maybe it's even safely wrapped in Collections.unmodifiableList ), there's no way to declare that in my return signature. 如果我返回一个List<Foo> ,我不想让人们修改(也许它甚至安全地包装在Collections.unmodifiableList ),那么就没有办法在我的返回签名中声明它。 As a poor-man's workaround, I'll often return List<? extends Foo> 作为一个穷人的解决方法,我会经常返回List<? extends Foo> List<? extends Foo> . List<? extends Foo> It's still possible to try to modify that list by removing elements or inserting null , but at least the fact that you can't add(new Foo()) serves as a bit of a reminder that this list is probably read-only. 仍然可以尝试通过删除元素或插入null来修改该列表,但至少无法add(new Foo())这一事实可以提醒您此列表可能是只读的。

More generally, I think returning something with a bounded return type is perfectly reasonable if you really want the call site to have restricted access to the object. 更一般地说,如果您真的希望调用站点具有对该对象的受限访问权限,我认为返回具有有界返回类型的内容是完全合理的。

Another example would be a thread-safe queue that you hand off to different threads, where one thread is a producer and the other is a consumer. 另一个例子是你交给不同线程的线程安全队列,其中一个线程是生产者而另一个是消费者。 If you give the producer a Queue<? super Foo> 如果你给生产者一个Queue<? super Foo> Queue<? super Foo> , it's clear that you intend them to put items into it (and not take items out). Queue<? super Foo> ,很明显你打算把它们放进去(而不是取出物品)。 Likewise, if you give the consumer a Queue<? extends Foo> 同样,如果你给消费者一个Queue<? extends Foo> Queue<? extends Foo> , it's clear you intend them to take items out (and not put items in). Queue<? extends Foo> ,很明显你打算把它们拿走(而不是放入物品)。

Can you use a bounded type parameter in the class declaration? 你能在类声明中使用有界类型参数吗?

class EnglishReaderOfPublications<E extends English> { ...

Then you can use this type parameter everywhere you have the wildcard parameter. 然后,您可以在具有通配符参数的任何位置使用此类型参数。

"ideally, the callers of getPublication wouldn't want the result as a bounded wildcard. They would be happy with Publication<English> ." “理想情况下,getPublication的调用者不希望将结果作为有界通配符。他们会对Publication<English>感到满意。”

Why "wouldn't" they want it? 为什么“不会”他们想要它? Would they "be happy" with Publication<? extends English> 他们会对Publication<? extends English> “感到高兴” Publication<? extends English> Publication<? extends English> ? Publication<? extends English> The question is really what these callers need to do with this Publication object. 问题实际上是这些调用者需要对此Publication对象执行的操作。 If all they do is get things out of it, then Publication<? extends English> 如果他们所做的一切都是从中得到的东西,那么Publication<? extends English> Publication<? extends English> is sufficient, and it is better because it is more general. Publication<? extends English>是足够的,它更好,因为它更通用。 However, if they need to put things into it, then you can't use Publication<? extends English> 但是,如果他们需要把东西放进去,那你就不能使用Publication<? extends English> Publication<? extends English> . Publication<? extends English>

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM