[英]Accessing a Java generics stored in a Map
我正在嘗試訪問存儲在地圖中的自定義Java通用,如下所示。
不幸的是我得到了類型錯誤匹配錯誤。
現在,我可以將它轉換為我想要的類型,但這對我來說似乎很混亂。
有沒有干凈的工作方式?
謝謝
public interface BusinessObject {
}
public class SalesItemA implements BusinessObject {
}
public interface BusinessRuleSuite<T extends BusinessObject> {
public void fire(T shell);
}
public abstract class BusinessRuleSuiteCommon<T extends BusinessObject>
implements BusinessRuleSuite<T> {
public synchronized void fire(T bo) {
// do something with bo;
}
}
public class SalesBusinessRuleSuite extends
BusinessRuleSuiteCommon<SalesItemA> {
}
public class SalesProcessor {
private final Map<Class<? extends BusinessObject>, BusinessRuleSuite<? extends BusinessObject>> businessRules;
public SalesProcessor(Map<Class<? extends BusinessObject>, BusinessRuleSuite<? extends BusinessObject>> businessRules) {
this.businessRules = businessRules;
}
public void processItem(SalesItemA sia) {
/// This assignment doesn't work??? Why?
BusinessRuleSuite<SalesItemA> p = this.businessRules.get(sia.getClass());
p.fire(sia);
}
}
}
因為get()
的返回類型是BusinessRuleSuite<? extends BusinessObject>
BusinessRuleSuite<? extends BusinessObject>
。
這意味着它將接受在put()
期間從BusinessObject
繼承的任何內容。 但是當你在賦值的右側使用它時,Java無法做出假設。 它必須安全,所以get()
行為就像你使用了BusinessRuleSuite<BusinessObject>
(沒有extends
)。
有兩種方法可以達到你想要的效果:
在地圖聲明中使用BusinessRuleSuite<SalesItemA>
使用演員
因為businessRules是一個
private final Map<Class<? extends BusinessObject>, BusinessRuleSuite<? extends BusinessObject>> businessRules
而不是
BusinessRuleSuite<SalesItemA> p = this.businessRules.get(sia.getClass());
做
BusinessRuleSuite<? extends BusinessObject> p = this.businessRules.get(sia.getClass());
Map
沒有為每個密鑰( Class<K>
, BusinessRuleSuite<V>
), K=V
服務員,我認為你的代碼是真的。
public class RuleProcessor<T extends BusinessObject> {
private final Map<Class<T>, BusinessRuleSuite<T>> businessRules;
public SalesProcessor(Map<Class<T>, BusinessRuleSuite<T>> businessRules) {
this.businessRules = businessRules;
}
// - or have a blank constructor, and add them one by one
public void add(Class<T> c, BusinessRuleSuite<T> rs) {
businessRules.add(c, rs);
}
public void processItem(T sia) {
BusinessRuleSuite<T> p = this.businessRules.get(sia.getClass());
p.fire(sia);
}
}
看起來您正在嘗試創建單個SalesProcessor
類,並更改其processItem
方法以接受BusinessObject
任何實現。
Neal Gafter試圖通過使用“超級型代幣”來擴展Josh Block的“類型安全的異類容器”模式, 但它有一些缺陷 。
您的地圖不包含SalesItemA類型的項目,但類型為<? 擴展BusinessObject>
更改
BusinessRuleSuite<SalesItemA> p = this.businessRules.get(sia.getClass());
至
BusinessRuleSuite<BusinessRuleSuite<? extends BusinessObject>> p = this.businessRules.get(sia.getClass());
......沒有經過實際測試,所以這可能根本不起作用。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.