我有一堆简单的界面:
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 );没有错误,但检查程序说:
类型安全:类型国家的表达需要未经检查的转换才能符合国家。
我不明白:通过调用以县为L-LineType和C是L的容器的服务方法,C是按国家作为C-类型的容器,因此,我期望类型推断会得出一个国家对象将被服务的结论。
有谁能解释一下,为什么我错了,我是否以及如何才能实现我想要的?
背景:作为服务的用户,我可以根据需要自由地组合容器和线路(只要服务提供者能够提供这些服务)。
发布于 2018-06-08 09:51:01
这是因为编译器不确定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);由于原始类型,这将在编译时再次发出警告。
发布于 2018-06-08 09:52:14
您的代码的问题是,国家可以有一个通用类型C扩展行,但使用您的方法。
getContainer( Country.class, County.class );这个方法没有告诉你这个Country.class有C类型的县。因此,从理论上讲,你返回的C将是国家。
不幸的是,除了抑制警告之外,没有真正的解决办法。或者,在Country中不使用参数,并将C固定到县。
public interface Country extends LineContainer<County>您也可以使用实际的对象或供应商等。
发布于 2019-06-03 14:40:53
我想我解决了..。
我问题中的主要错误是,我想在容器中定义行元素。现在,我在行中定义它属于什么标题。
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 );因为县不是一条“线”.
https://stackoverflow.com/questions/50757383
复制相似问题