2016-08-29 2 views
0

Для некоторых исторических причин, почему я должен использовать абстрактный класс с двумя подстановочных параметрами:Java Wildcard отливать подтип

AbstractColumn<M, I> 

И у меня есть реализация (IDataSource является интерфейсом):

SimpleColumn<I> extends AbstractColumn<IDataSource<I>, I> 

Проблема начинается, когда я должен применить параметр IDataSource<I> к его реализации, например GenericDataSource<I>:

SimpleColumn<I> column; 
AbstractColumn<GenericDataSource<I>, <I>> newColumn = 
     (AbstractColumn<GenericDataSource<I>, <I>>)column; 

Я получаю сообщение об ошибке:

Type mismatch: cannot convert from AbstractColumn<GenericDataSource<I>,I> to AbstractColumn<IDataSource<I>,I> 

И если я пытаюсь преобразовать IDataSource объект (не параметр) в GenericDataSource, нет никаких ошибок:

IDataSource<T> ds; 
GenericDataSource<T> gds = (GenericDataSource<T>)ds; 

Почему java способен преобразовывать IDataSource в GenericDataSource, но не может сделать то же самое в шаблоне?

+2

Проблема заключается в том, что в то время как '' GenericDataSource является подклассом '' IDataSource , и, следовательно, может быть отлит, 'AbstractColumn , >' не является подкласс или суперкласс '' SimpleColumn . –

+2

Также подстановочный знак является '?', Вы, кажется, говорите об общих параметрах. –

+0

кажется, что из этого вы не сможете получить информацию. У Pheraps есть лучшие способы сделать это. Можете ли вы опубликовать полный код SimpleColumn и AbstactColumn? – Onheiron

ответ

0

Дженерики сложны в лучшие времена. Для начала, вот два бита кода. Первый (ваш код) не компилируется. Второй компилируется. Разница заключается в параметре типа AbstractColumn.

SimpleColumn<I> column = null; 

    AbstractColumn<GenericDataSource<I>, I> newColumn1; 
    newColumn1 = (AbstractColumn<GenericDataSource<I>, I>)column; 

    AbstractColumn<IDataSource<I>, I> newColumn2; 
    newColumn2 = (AbstractColumn<IDataSource<I>, I>)column; 

Обычно я решить эту проблему, поставив «? Расширяет I» или «? Супер я» в одном из параметров типа. Однако в этом случае это не работает. Также обратите внимание, что параметр второго типа в AbstractColumn не имеет значения - его удаление также не решает проблему.

SimpleColumn<I> column = null; 

    AbstractColumn<GenericDataSource<I>> newColumn1; 
    newColumn1 = (AbstractColumn<GenericDataSource<I>>)column; 

    AbstractColumn<IDataSource<I>> newColumn2; 
    newColumn2 = (AbstractColumn<IDataSource<I>>)column; 

Я думаю, что проблема, с которой вы сталкиваетесь, связана с стиранием типа времени компиляции. В принципе, когда программа скомпилирована, все параметры типа преобразуются в «Объект». Компилятор понял, что в этом конкретном случае он не сможет выполнить правильный листинг (и повысить класс ClassCastException), поэтому блокирует вас от этого. Нам, вероятно, нужен Гуру Java Generics для изучения этого!

+0

Спасибо за расширенный комментарий ;-) Но почему '' не работает? Из-за IDataSource это интерфейс? –