首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >泛型键/值与相关类型的泛型映射

泛型键/值与相关类型的泛型映射
EN

Stack Overflow用户
提问于 2010-02-05 23:40:22
回答 4查看 15.6K关注 0票数 15

我正在尝试创建一个泛型类型,该类型保存已创建的自身版本的映射,以供以后使用。实际上,它是一个单例模式,其中每个类型都有一个实例。到目前为止,我拥有的代码是:

代码语言:javascript
运行
复制
public class FieldBinder<T> {
    static final Map<Class<? extends Object>,FieldBinder<? extends Object>> instanceMap = 
        new HashMap<Class<? extends Object>,FieldBinder<? extends Object>>();

    private FieldBinder() {}

    synchronized public static <V extends Object> FieldBinder<V> getInstance(Class<V> klass) {
        if(!instanceMap.containsKey(klass)) {
            instanceMap.put(klass, new FieldBinder<V>());
        }
        return (FieldBinder<V>)instanceMap.get(klass);
    }
}

然而,我仍然不确定我是不是“做对了”。我觉得我应该能够指定这个集合是(类-> FieldBinder)。IDE对return语句发出警告的事实只会强化这一想法。

有没有更好的方法来处理这件事?

注意:This question看起来关系非常密切,但距离太远了,以至于我不知道如何将其中的信息应用到我自己的问题中。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2010-02-05 23:54:57

您的实现是正确的。没有“更好”的方法(如果有这样的事情在代码中是“更好的”,这是另一回事。)

次要修复:

  • <V extends Object>等同于较少的V verbose
  • Class<? extends Object>等效于较少冗长的Class<?>
  • 您可以使用@SuppressWarnings("unchecked")注解来告诉编译器强制转换是安全的
票数 15
EN

Stack Overflow用户

发布于 2010-02-06 03:22:35

我认为如果没有一个未经检查的角色,就不可能做到这一点。您需要类似于Haskell的existential types的东西,而Java没有。

您可以让客户端执行未经检查的强制转换。

代码语言:javascript
运行
复制
synchronized public static <V> FieldBinder<V>
getInstance(Class<V> klass, Class<FieldBinder<V>> binderKlass) {
    if(!instanceMap.containsKey(klass)) {
        instanceMap.put(klass, new FieldBinder<V>());
    }
    return binderKlass.cast(instanceMap.get(klass));
}

现在,如果客户端将Class<FieldBinder<V>>传递给getInstance()方法,则可以避免在getInstance()中进行未经检查的强制转换。

不幸的是,创建Class<FieldBinder<V>>本身需要一个未经检查的强制转换。

代码语言:javascript
运行
复制
Class<FieldBinder<Integer>> binderKlass =
    (Class<FieldBinder<Integer>>) (Class<?>) FieldBinder.class;
BinderAssociator.getInstance(Integer.class, binderKlass);
票数 3
EN

Stack Overflow用户

发布于 2010-02-06 22:24:29

RHSeeger我明白你原来的问题了我找不到解决这个问题的办法。您可以尝试使用的是一个MyMap类,它可以根据您的请求进行绑定。然而,使用此映射会出现两个问题:

  1. 因为它被声明为MyMap<?>,所以不能向其添加具有给定类型的内容。这是虚构的,我建议你参考Java Generics FAQs (参见案例研究3)了解更多细节。
  2. As map在键和值之间有联系,一个人不能添加任何类型的两个独立对象(两个<?>表示不同的类型),因为这两个类型可能没有连接。

在玩的时候,我看到了一些错误,我自己也无法解释。我认为,每一件事都涉及到一个事实(正如我之前提到的),我们试图处理第二级参数化。

代码语言:javascript
运行
复制
    class FieldBinder<T> {
        static class MyMap<M> extends HashMap<Class<M>, FieldBinder<M>> {
        }
        static final MyMap<?> instanceMap1 = new MyMap<Object>();
        static final Map<Class<?>, FieldBinder<?>> instanceMap2 = new HashMap<Class<?>, FieldBinder<?>>();
        public static <V> void test() {
            Class<V> c1 = null;
            FieldBinder<V> f1 = null;
            Class<?> c2 = null;
            FieldBinder<?> f2 = null;
            instanceMap1.put(c1, f1); // error (see 1)
            instanceMap1.put(c2, f2); // error (see 2)
            instanceMap2.put(c1, f1); // ok
            instanceMap2.put(c2, f2); // ok
            instanceMap2.put(c1, f2); // wish to be an error, but ok
            instanceMap2.put(c2, f1); // wish to be an error, but ok
        }
    }
票数 3
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2208317

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档