Java bounded wildcard in return type

五迷三道 提交于 2019-12-18 05:37:19

问题


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. They would be happy with Publication<English>.

Is there a way round this?


回答1:


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. 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. As a poor-man's workaround, I'll often return 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.

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>, it's clear that you intend them to put items into it (and not take items out). Likewise, if you give the consumer a Queue<? extends Foo>, it's clear you intend them to take items out (and not put items in).




回答2:


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.




回答3:


"ideally, the callers of getPublication wouldn't want the result as a bounded wildcard. They would be happy with Publication<English>."

Why "wouldn't" they want it? Would they "be happy" with Publication<? extends English>? The question is really what these callers need to do with this Publication object. If all they do is get things out of it, then Publication<? extends English> is sufficient, and it is better because it is more general. However, if they need to put things into it, then you can't use Publication<? extends English>.



来源:https://stackoverflow.com/questions/8966502/java-bounded-wildcard-in-return-type

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!