繁体   English   中英

Generics 混乱

[英]Generics confusion

通用标题道歉,我真的想不出一种方法来解释这一点。

我想 model 一个系统向用户提供设施的场景,这些设施具有应用于针对这些设施的请求的相关策略

public interface Facility {
    public List<Policy> getPolicies();
}
public interface Policy {
    public void apply(Facility facility, Request request);
}
public interface Request {

}

但是请求只能对特定类型的设施有意义,并且策略实际上只能适用于一种类型的设施和特定于该类型设施的请求类型。

public interface Facility<F extends Facility<F>> {
    public List<Policy<F, ? extends Request<F>>> getPolicies();
}
public interface Policy<F extends Facility<F>, R extends Request<F>> {
    public void apply(F facility, R request);
}
public interface Request<F extends Facility<F>> {

}

但我也希望能够总体上指定策略,以便它们可以应用于任何 Facility 超类型。

public interface Facility<F extends Facility<F>> {
    public List<Policy<? super F, ? extends Request<F>>> getPolicies();
}

但实际上,您只想查询适用于特定类型的设施请求的策略。

public interface Facility<F extends Facility<F>> {
    public <R extends Request<F>> List<Policy<? super F, R>> getPolicies();
}

我的问题是现在我对所有 generics 感到非常困惑,我什至无法创建适用于所有设施的策略 class,如果合法的话,这将是这样的

public class GeneralPolicy implements Policy<T extends Facility<T>, Request<T>>

我如何以根据上述描述有意义的方式关联设施、策略和请求的类型? 我敢肯定人们会要求澄清,我已经与这个斗争了足够长的时间,我可能没有解释什么,或者完全错过了一个明显的点。

如果我没看错的话,您真正想做的是获取适用于 R 的所有策略。

public interface Facility<F extends Facility<F>> {
    public <R extends Request<F>> List<Policy<? super F, R>> getPolicies();
}

不幸的是,由于类型擦除,您不能。 在运行时,编译器不知道 R 是什么。

但是,您可以将 class 传递到:

public interface Facility<F extends Facility<F>> {
    public <R extends Request<F>> List<Policy<? super F, R>> getPolicies(Class<R> requestClass);
}

然后 Policy 也需要返回其请求类型:

public interface Policy<F extends Facility<F>, R extends Request<F>> {
    public void apply(F facility, R request);

    public Class<R> getRequestClass();
}

然后,设施的实现可以通过可用策略列表,检查策略的请求类型是否与实际请求的类型匹配,并返回该子集。

对于全局策略,该策略可以返回 Request.class。 对于特定的,MyRequest.class。

此外,我会说 Facility (至少你在那里拥有它的方式)不需要被泛化,它会使代码更简单。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM