簡體   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