2010-11-16 51 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); 
    } 
}