Java ограниченный шаблон в типе возврата - PullRequest
16 голосов
/ 23 января 2012

Я читал в разных местах, включая здесь , что наличие ограниченного подстановочного знака в типе возврата метода является плохой идеей.Тем не менее, я не могу найти способ избежать этого с моим классом.Я что-то упускаю?

Ситуация выглядит примерно так:

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>.

Есть ли способ обойти это?

Ответы [ 3 ]

13 голосов
/ 23 января 2012

Ограниченные подстановочные знаки являются заразными, что, по-видимому, вызывает сожаление на странице, на которую вы ссылаетесь. Ну, это нельзя отрицать ... но я думаю, что не вижу в этом такой большой проблемы.

Во многих случаях я возвращаю ограниченный подстановочный знак точно , потому что это заразно. JDK, к лучшему или к худшему (я говорю к худшему, но это другая мыльница :)), не имеет интерфейсов для коллекций только для чтения. Если я возвращаю List<Foo>, который я не хочу, чтобы люди модифицировали (возможно, он даже безопасно завернут в Collections.unmodifiableList), я не смогу заявить об этом в моей подписи. Как обходной путь бедняка, я часто возвращаюсь List<? extends Foo>. Все еще можно попытаться изменить этот список, удалив элементы или вставив null, но хотя бы тот факт, что вы не можете add(new Foo()), служит напоминанием о том, что этот список, вероятно, доступен только для чтения.

В целом, я думаю, что возвращение чего-либо с ограниченным типом возврата вполне разумно, если вы действительно хотите, чтобы сайт вызова имел ограниченный доступ к объекту.

Другим примером может быть потокобезопасная очередь, которую вы передаете разным потокам, где один поток является производителем, а другой - потребителем. Если вы дадите продюсеру Queue<? super Foo>, ясно, что вы намереваетесь положить в него предметы (а не вынимать предметы). Точно так же, если вы дадите потребителю Queue<? extends Foo>, ясно, что вы намереваетесь вывести его (а не положить).

5 голосов
/ 23 января 2012

Можно ли использовать параметр ограниченного типа в объявлении класса?

class EnglishReaderOfPublications<E extends English> { ...

Тогда вы можете использовать этот параметр типа везде, где есть параметр подстановки.

0 голосов
/ 23 января 2012

"в идеале, вызывающие getPublication не хотели бы, чтобы результат был ограниченным подстановочным знаком. Они были бы довольны Publication<English>."

Почему бы "не" они этого хотели?Будут ли они "счастливы" с Publication<? extends English>?Вопрос в том, что эти вызывающие стороны должны делать с этим объектом Publication.Если все, что они делают, это извлекают из этого что-то, то Publication<? extends English> достаточно, и это лучше, потому что оно более общее.Однако, если им нужно вложить что-то в это, вы не можете использовать Publication<? extends English>.

...