首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >带仿制药的类型安全性

带仿制药的类型安全性
EN

Stack Overflow用户
提问于 2018-06-08 09:22:19
回答 3查看 333关注 0票数 4

我有一堆简单的界面:

代码语言:javascript
复制
interface County extends Line{}

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

interface Line {}

interface LineContainer <L extends Line> {
    public List<L> getLines();
}

和服务方法

代码语言:javascript
复制
public static <L extends Line,C extends LineContainer<L>> C getContainer( Class<C> containerType, Class<L> lineType ){
    ...somthing...

调用服务方法

代码语言:javascript
复制
Country<County> c = getContainer( Country.class, County.class );

没有错误,但检查程序说:

类型安全:类型国家的表达需要未经检查的转换才能符合国家。

我不明白:通过调用以县为L-LineType和C是L的容器的服务方法,C是按国家作为C-类型的容器,因此,我期望类型推断会得出一个国家对象将被服务的结论。

有谁能解释一下,为什么我错了,我是否以及如何才能实现我想要的?

背景:作为服务的用户,我可以根据需要自由地组合容器和线路(只要服务提供者能够提供这些服务)。

EN

回答 3

Stack Overflow用户

发布于 2018-06-08 09:51:01

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

如果你写这个:

代码语言:javascript
复制
public static <L extends Line, C extends LineContainer<L>> C getContainer(C container, Class<L> lineType) {
    return null;
}

以及:

代码语言:javascript
复制
Country<County> c = getContainer(new Country<County>() {
    @Override
    public List<County> getLines() {
        return null;
    }
}, County.class);

很明显这是可行的。

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

代码语言:javascript
复制
    Country foo = new Country<County>() {
        @Override
        public List<County> getLines() {
            return null;
        }
    };
    Country<County> c = getContainer(foo, County.class);

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

票数 1
EN

Stack Overflow用户

发布于 2018-06-08 09:52:14

您的代码的问题是,国家可以有一个通用类型C扩展行,但使用您的方法。

代码语言:javascript
复制
getContainer( Country.class, County.class );

这个方法没有告诉你这个Country.class有C类型的县。因此,从理论上讲,你返回的C将是国家。

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

代码语言:javascript
复制
public interface Country extends LineContainer<County>

您也可以使用实际的对象或供应商等。

票数 0
EN

Stack Overflow用户

发布于 2019-06-03 14:40:53

我想我解决了..。

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

代码语言:javascript
复制
interface Line<R> {}

我定义了一个LineContainer,它服务于定义类型中的行

代码语言:javascript
复制
interface LineContainer<H, L extends Line<H>> {
    public List<L> getLines();
}

现在,我可以定义一个通用服务方法(看起来与上面的方法略有不同):

代码语言:javascript
复制
public static <H,L extends Line<H>,C extends LineContainer<H,L>> C getContainer( Class<C> containerType, Class<L> lineType ){
   // ...something...
}

国家和县的定义如下:

代码语言:javascript
复制
interface County extends Line<Country>{}
interface Country extends LineContainer<Country,County>{};

我现在可以毫无问题地使用:

代码语言:javascript
复制
LineContainer<Country,County> container = getContainer( Country.class, County.class );

LineContainer和Line的另一个示例:

代码语言:javascript
复制
interface Note extends Line<Gamut>{}
interface Gamut extends LineContainer<Gamut,Note>{};
LineContainer<Gamut,Note> container = getContainer( Gamut.class, Note.class );

服务方法必须检查是否可以提供所需的类型,但是服务的用户不能组合不可燃烧的类型:

不允许

代码语言:javascript
复制
LineContainer<Gamut,County> container = getContainer( Gamut.class, County.class );

因为县不是一条“线”.

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/50757383

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档