Java 使用泛型的类型安全性

Java 使用泛型的类型安全性,java,generics,type-conversion,unchecked-conversion,Java,Generics,Type Conversion,Unchecked Conversion,我有很多简单的界面: interface County extends Line{} interface Country<C extends Line> extends LineContainer<C> {} interface Line {} interface LineContainer <L extends Line> { public List<L> getLines(); } 接口扩展行{} 接口国家/地区扩展LineCo

我有很多简单的界面:

interface County extends Line{}

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

interface Line {}

interface LineContainer <L extends Line> {
    public List<L> getLines();
}
接口扩展行{}
接口国家/地区扩展LineContainer{}
接口线{}
接口行容器{
公共列表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 );
publicstaticgetcontainer(类containerType,类lineType){
…糟糕的事。。。
调用服务方法

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 );
Country c=getContainer(Country.class,Country.class);
没有错误,但检查人员说:

类型安全性:类型Country的表达式需要未经检查的转换才能符合Country

我不明白: 通过调用服务方法,使用County作为L-LineType,C是L的容器,C由Country作为C-Type给出,因此,我希望类型推断会得出结论,将为Country对象提供服务

谁能解释一下,为什么我错了,如果我能实现我想要的,我该如何实现


背景:这个想法是——作为服务的用户——我可以根据需要自由组合容器和行(只要服务提供商可以提供这些容器和行)

这是因为编译器不确定
Country.class
是否与签名
Country
Country.class匹配。class被视为原始类型

如果你这样写:

public static <L extends Line, C extends LineContainer<L>> C getContainer(C container, Class<L> lineType) {
    return null;
}
公共静态C getContainer(C容器,类线型){
返回null;
}
以及:

Country c=getContainer(新国家(){
@凌驾
公共列表getLines(){
返回null;
}
},县(级);
显然,这是可行的

现在想象一下,我将相同的代码拆分为另一种方式:

    Country foo = new Country<County>() {
        @Override
        public List<County> getLines() {
            return null;
        }
    };
    Country<County> c = getContainer(foo, County.class);
Country foo=新国家(){
@凌驾
公共列表getLines(){
返回null;
}
};
国家c=getContainer(foo,County.class);

由于原始类型的原因,这将在编译时再次发出警告。

代码的问题是,国家/地区可能有一个扩展行的泛型类型C,但是使用您的方法

getContainer( Country.class, County.class );
此方法不会告诉您This Country.class具有C类型的Country。因此,理论上,您返回的C将是Country

不幸的是,除了抑制警告,或者在Country中不使用参数并将C固定为County之外,没有真正的解决方法

public interface Country extends LineContainer<County>
公共接口国家/地区扩展LineContainer
你也可以使用实物或供应商等。

我想我已经解决了

我问题中的主要错误是,我想在容器中定义行元素,现在我在行中定义它所属的标题

interface Line<R> {}
接口行{}
然后,我定义了一个LineContainer,它为定义类型中的行提供服务

interface LineContainer<H, L extends Line<H>> {
    public List<L> getLines();
}
接口行容器{
公共列表getLines();
}
现在我可以定义一个通用服务方法(看起来与我上面的方法略有不同):

publicstaticgetcontainer(类containerType,类lineType){
//…有些事。。。
}
这样定义国家和县:

interface County extends Line<Country>{}
interface Country extends LineContainer<Country,County>{};
接口扩展行{}
接口国扩展LineContainer{};
我现在可以毫无问题地使用:

LineContainer<Country,County> container = getContainer( Country.class, County.class );
LineContainer=getContainer(Country.class,Country.class);
LineContainer和Line的另一个示例:

interface Note extends Line<Gamut>{}
interface Gamut extends LineContainer<Gamut,Note>{};
LineContainer<Gamut,Note> container = getContainer( Gamut.class, Note.class );
接口注释扩展了第{}行
接口色域扩展LineContainer{};
LineContainer=getContainer(Gamut.class,Note.class);
服务方法必须检查是否可以提供所需的类型,但服务用户不能组合不可兼容的类型:

不允许

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

由于County不是一个色域中的“Line”…

谢谢,但是这个想法是,调用者可能会决定使用Line对象而不是County对象创建一个国家(想想,Line提供一些基本属性,而County有一些在当前调用中不需要的附加属性)