我正在尝试创建一个泛型类型,该类型保留了为以后使用而创建的自身版本的映射。实际上,它是一个单例模式,每种类型都有一个实例。我到目前为止的代码是:
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);
}
}
然而,我仍然不确定我“做得对”。感觉我应该能够指定集合是(Class - &gt; FieldBinder)。 IDE警告返回语句的事实只会加强这种想法。
有没有更好的方法来解决这个问题?
注意:This question似乎非常密切相关,但距离足够远,我无法弄清楚如何将信息应用于我自己的问题。
答案 0 :(得分:15)
您的实施是正确的。没有“更好”的方法(如果在代码中有这样的东西“更好”,这是另一个问题..)
次要修正:
<V extends Object>
相当于V
,不那么详细Class<? extends Object>
相当于Class<?>
,不那么详细@SuppressWarnings("unchecked")
注释告诉编译器演员阵容是安全的答案 1 :(得分:3)
如果没有一个未经检查的演员,我认为不能做到。你需要类似于Haskell的existential types,这是Java没有的。
您可以让客户端执行未经检查的强制转换......
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>>
本身需要一个未选中的强制转换。
Class<FieldBinder<Integer>> binderKlass =
(Class<FieldBinder<Integer>>) (Class<?>) FieldBinder.class;
BinderAssociator.getInstance(Integer.class, binderKlass);
答案 2 :(得分:3)
RHSeeger,我收到了你原来的问题。我找不到解决问题的方法。您可以尝试使用的是MyMap类,它可以根据您的要求进行绑定。然而,有了这张地图,就会出现两个问题:
MyMap<?>
,因此无法向其添加具有给定类型的内容。这是虚拟的,我将您推荐给Java Generics FAQs(参见案例研究3)了解更多详情。<?>
引用不同类型),因为这两种类型可能未连接。在玩的时候,我看到了一些错误,我无法解释。我认为,一切都进入事实(正如我之前提到的),我们试图处理第二级参数化。
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 :(得分:1)
您引用的示例告诉我,如何恢复对象的类型(类),同时需要恢复参数化的类型(类)。这是不可能的。