2010-11-16 55 views
2

我一直在閱讀Effective Java,並決定嘗試將我學到的一些東西付諸行動。我試圖有效地創建一個Multimap<?, Condition<?> >,其中通配符對於鍵和值都是相同的類型,但它會有所不同,不同的類型。Java通過泛型類型存儲條件

這裏是一本書,我在看項目:Item 29

我並不想完全複製它。我意識到最大的不同是關鍵不直接代表鏈接的價值。在我的,關鍵代表價值的通用類型。

所以我會做mmap.put(Class<Integer>, ConditionMapping<Integer>) 當我做得到我沒有泛型類型的ConditionMapping,所以我得到了未經檢查的轉換警告。

我有我想有簽名<T> List<Condition <T> >(Class<T> type)

由於類型擦除get方法,是我以確保condition.value是T型的,建設對象的新名單唯一的選擇?

我可以忽略未經檢查的投射警告,但我只是不想。有什麼建議麼?提示?竅門?

回答

1

沒有辦法表示兩個通配符應該捕獲相同的類型。請參閱this question以瞭解類似的情況和一些可能的解決方案。

0

您可以製作一個MyClass,然後將自己的類型傳遞給它,並在其中封裝Multimap。 Java中的模板不可能通常可以通過添加另一個層來解決,也就是說,可以通過添加另一個層來模擬真正想要的類,因爲您可以通過這種方式獲得「T」類型,然後將其用於列表或地圖,並且保證從此以後的多個模板都是一樣的。

+0

我不確定我是否收到你。你是說像定義一個IntCondition或一個StringCondition?我在哪裏做IntCondition擴展條件?或者你說make Condition是一個類型還是從創建的實例中獲取類型?或者爲每種類型製作一個單獨的容器? – Scott 2010-11-16 14:26:52

0

這可能是向正確方向邁出的一步。

<Multimap<Class<?>, Condition<?>> 
+0

不幸的是,這將允許'put(String.class,new Condition ())' – finnw 2011-02-01 15:03:52

1

如果你讓你的界面擴展Multimap<Void, Condition<?>>它允許用戶調用一些不依賴型安全性(如的containsKey),但不添加條目(繞過你的類型檢查代理方法)的方法,除非他們使用未經檢查的強制轉換。

interface ConditionMapBase<T> extends Multimap<T, Condition<?>> { 
} 
interface ConditionMap extends ConditionMapBase<Void> { 
    <T>boolean putCondition(T key, Condition<T> value); 
    <T>Collection<Condition<T>> getConditions(T key); 
} 
class ConditionMapImpl 
extends ForwardingMultimap<Void, Condition<?>> 
implements ConditionMap { 

    ConditionMapImpl() { 
     delegate = HashMultimap.create(); 
    } 
    @SuppressWarnings("unchecked") 
    @Override 
    protected Multimap<Void, Condition<?>> delegate() { 
     return (Multimap<Void, Condition<?>>) (Multimap<?, ?>) delegate; 
    } 
    private final Multimap<Object, Condition<?>> delegate; 
    @SuppressWarnings("unchecked") 
    @Override 
    public <T> Collection<Condition<T>> getConditions(T key) { 
     return (Collection<Condition<T>>) (Collection<?>) ((ConditionMapBase<T>) this).get(key); 
    } 
    @SuppressWarnings("unchecked") 
    @Override 
    public <T> boolean putCondition(T key, Condition<T> value) { 
     return ((ConditionMapBase<T>) this).put(key, value); 
    } 
}