Ограниченный шаблон Java в обратном типе - программирование
Подтвердить что ты не робот

Ограниченный шаблон Java в обратном типе

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

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

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

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

4b9b3361

Ответ 1

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

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

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

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

Ответ 2

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

class EnglishReaderOfPublications<E extends English> { ...

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

Ответ 3

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

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