Тип безопасности с генериками - PullRequest
0 голосов
/ 08 июня 2018

У меня есть несколько простых интерфейсов:

interface County extends Line{}

interface Country<C extends Line> extends LineContainer<C> {}

interface Line {}

interface LineContainer <L extends Line> {
    public List<L> getLines();
}

И метод обслуживания

public static <L extends Line,C extends LineContainer<L>> C getContainer( Class<C> containerType, Class<L> lineType ){
    ...somthing...

Вызов метода обслуживания

Country<County> c = getContainer( Country.class, County.class );

не вызывает ошибок,но проверяющий говорит:

Безопасность типа: Выражение типа Страна требует неконтролируемого преобразования для соответствия стране

Я не понимаю, что: путем вызова метода обслуживанияс County в качестве L-LineType, а C является контейнером для L, а C задается Country как C-тип, поэтому я ожидал, что вывод типа сделает вывод, что объект Country будет обслуживаться.

МожетКто-нибудь объяснит, почему я не прав, и если и как я могу достичь того, чего я хочу?

Справочная информация: Идея заключается в том, чтобы - как пользователь службы - я мог свободно комбинировать контейнеры и строки по мере необходимости (так какпока поставщик услуг может их обслуживать)

Ответы [ 3 ]

0 голосов
/ 08 июня 2018

Проблема с вашим кодом заключается в том, что Страна может иметь Универсальный Тип C, который расширяет Строку, однако используя ваш метод.

getContainer( Country.class, County.class );

Этот метод не говорит вам, что этот Country.class имеет Cтип округа .. поэтому в теории ваш возврат C будет страна.

К сожалению, для этого нет другого решения, кроме как подавить предупреждение.Или вы не используете параметр в стране и делаете C привязанным к графству.

public interface Country extends LineContainer<County>

Вы также можете использовать реальные объекты или поставщиков и т. Д.

0 голосов
/ 03 июня 2019

Я думаю, что решил это ...

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

interface Line<R> {}

Затем я определяю LineContainer, который обслуживает строки из определенного типа

interface LineContainer<H, L extends Line<H>> {
    public List<L> getLines();
}

Теперь я могу определить универсальный сервисМетод (выглядит немного иначе, чем мой подход выше):

public static <H,L extends Line<H>,C extends LineContainer<H,L>> C getContainer( Class<C> containerType, Class<L> lineType ){
   // ...something...
}

Определение страны и округа следующим образом:

interface County extends Line<Country>{}
interface Country extends LineContainer<Country,County>{};

Теперь я могу использовать без проблем:

LineContainer<Country,County> container = getContainer( Country.class, County.class );

Другой пример с LineContainer и Line:

interface Note extends Line<Gamut>{}
interface Gamut extends LineContainer<Gamut,Note>{};
LineContainer<Gamut,Note> container = getContainer( Gamut.class, Note.class );

Метод службы должен проверить, могут ли обслуживаться требуемые типы, но пользователь службы не может объединять типы, которые не совместимы:

НЕ РАЗРЕШЕНО

LineContainer<Gamut,County> container = getContainer( Gamut.class, County.class );

, поскольку округ не является "линией" гаммы ...

0 голосов
/ 08 июня 2018

Это потому, что компилятор не уверен, что Country.class соответствует подписи Country<County>.Country.class считается необработанным типом.

Если вы напишите это:

public static <L extends Line, C extends LineContainer<L>> C getContainer(C container, Class<L> lineType) {
    return null;
}

и:

Country<County> c = getContainer(new Country<County>() {
    @Override
    public List<County> getLines() {
        return null;
    }
}, County.class);

Очевидно, это работает.

Сейчаспредставьте, что я разделил этот код по-другому:

    Country foo = new Country<County>() {
        @Override
        public List<County> getLines() {
            return null;
        }
    };
    Country<County> c = getContainer(foo, County.class);

Это снова выдаст предупреждение во время компиляции из-за необработанного типа.

...