簡體   English   中英

訪問存儲在Map中的Java泛型

[英]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 )。

有兩種方法可以達到你想要的效果:

  1. 在地圖聲明中使用BusinessRuleSuite<SalesItemA>

  2. 使用演員

因為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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM