Type safety with generics
我有很多简单的界面:
1 2 3 4 5 6 7 8 9 |
以及一种服务方法
1 2 | public static <L extends Line,C extends LineContainer<L>> C getContainer( Class<C> containerType, Class<L> lineType ){ ...somthing... |
调用服务方法
1 | Country<County> c = getContainer( Country.class, County.class ); |
不会出错,但检查人员说:
Type safety: The expression of type Country needs unchecked conversion to conform to Country
我不明白:通过调用以County为L-Linetype,C为L的容器,C为C-Type的容器,由Country给出C的容器,我期望类型推断可以得出Country对象将被服务的结论。
有人能解释,为什么我是错的,如果我能实现我想实现的目标,我又如何做到?
背景:我的想法是-作为服务的用户-我可以根据需要自由组合容器和行(只要服务提供商可以提供这些服务)
这是因为编译器不确定
如果你这样写:
1 2 3 | public static <L extends Line, C extends LineContainer<L>> C getContainer(C container, Class<L> lineType) { return null; } |
还有:
1 2 3 4 5 6 | Country<County> c = getContainer(new Country<County>() { @Override public List<County> getLines() { return null; } }, County.class); |
显然这是可行的。
现在假设我将相同的代码拆分成另一种方式:
1 2 3 4 5 6 7 | Country foo = new Country<County>() { @Override public List<County> getLines() { return null; } }; Country<County> c = getContainer(foo, County.class); |
由于原始类型的原因,这将在编译时再次发出警告。
您的代码的问题是,国家可以有一个扩展行的通用类型C,但是使用您的方法。
1 | getContainer( Country.class, County.class ); |
此方法没有告诉您Country.Class具有County的C类型。因此,理论上,你的回报率C是国家。
不幸的是,除了取消警告之外,没有真正的解决方法。或者您不在国家使用参数,而将C固定到县。
1 | public interface Country extends LineContainer<County> |
您还可以使用实际对象或供应商等。