2

我一直在阅读 Effective Java 并决定尝试将我学到的一些知识付诸实践。我正在尝试有效地创建一个Multimap<?, Condition<?> > 通配符对于键和值来说都是相同类型的,但它将是不同的、不同的类型。

这是我正在看的书中的项目:项目 29

我不想完全复制它。我意识到最大的区别是键不直接代表链接中的值。在我看来,键代表值的通用类型。

因此,mmap.put(Class<Integer>, ConditionMapping<Integer>) 当我执行 get 时,我没有 ConditionMapping 的泛型类型,所以我会收到 unchecked cast 警告。

我有一个我想要签名的 get 方法<T> List<Condition <T> >(Class<T> type)

由于类型擦除,我唯一的选择是确保 condition.value 是 T 类型并构建新的对象列表吗?

我可以忽略未经检查的演员表警告,但我只是尽量不这样做。有什么建议么?提示?诡计?

4

4 回答 4

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);
    }
}
于 2011-02-01T15:02:51.023 回答
1

没有办法表示两个通配符应该捕获相同的类型。有关类似情况和许多可能的解决方案,请参阅此问题。

于 2011-02-01T15:12:30.503 回答
0

您可以创建一个 MyClass,然后将您自己的类型传递给它,并将 Multimap 封装在其中。Java 中的模板不可能性通常可以通过添加另一个层来解决,可以这么说,并围绕您真正想要的内容模板化一个类,因为您可以通过这种方式获得“T”类型,然后您可以将其用于列表或地图,以及保证从那时起它对于多个模板是相同的。

于 2010-11-16T14:12:47.727 回答
0

这可能是朝着正确方向迈出的一步。

<Multimap<Class<?>, Condition<?>>
于 2011-02-01T11:55:42.227 回答