由于某些历史原因,我必须使用带有两个通配符参数的抽象类:
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
,但不能在通配符中执行相同操作?
答案 0 :(得分: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;
通常我会通过放置&#34;来解决这个问题。扩展我&#34;或&#34;?超级我&#34;在其中一个类型参数中。但是,在这种情况下,这是行不通的。另请注意,AbstractColumn的第二个类型参数并不重要 - 删除它也不能解决问题。
SimpleColumn<I> column = null;
AbstractColumn<GenericDataSource<I>> newColumn1;
newColumn1 = (AbstractColumn<GenericDataSource<I>>)column;
AbstractColumn<IDataSource<I>> newColumn2;
newColumn2 = (AbstractColumn<IDataSource<I>>)column;
我认为您遇到的问题与编译时类型擦除有关。基本上,在编译程序时,所有类型参数都转换为&#34; Object&#34;。编译器已经意识到在这种特殊情况下,它将无法执行正确的强制转换(并引发ClassCastException),因此阻止您执行此操作。我们可能需要Java Generics Guru来研究这个问题!