具有相关类型的通用键/值的通用映射

我正在尝试创建一个generics类型,该类型保留了为以后使用而创建的自身版本的映射。 实际上,它是一个单例模式,每种类型都有一个实例。 我到目前为止的代码是:

public class FieldBinder { static final Map<Class,FieldBinder> instanceMap = new HashMap<Class,FieldBinder>(); private FieldBinder() {} synchronized public static  FieldBinder getInstance(Class klass) { if(!instanceMap.containsKey(klass)) { instanceMap.put(klass, new FieldBinder()); } return (FieldBinder)instanceMap.get(klass); } } 

但是,我仍然不确定我“做得对”。 感觉我应该能够指定集合是(Class – > FieldBinder)。 IDE警告返回语句的事实只会加强这种想法。

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

注意: 这个问题看起来非常密切相关,但距离足够远,我无法弄清楚如何将信息应用到我自己的问题中。

您的实施是正确的。 没有“更好”的方法(如果在代码中有这样的东西“更好”,这是另一个问题..)

小修正:

  • 相当于V ,它的详细程度较低
  • Class Class等同于Class ,它不那么详细
  • 您可以使用@SuppressWarnings("unchecked")注释告诉编译器@SuppressWarnings("unchecked")是安全的

如果没有一个未经检查的演员,我认为不能做到这一点。 你需要类似于Haskell的存在类型 ,Java没有。

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

 synchronized public static  FieldBinder getInstance(Class klass, Class> binderKlass) { if(!instanceMap.containsKey(klass)) { instanceMap.put(klass, new FieldBinder()); } return binderKlass.cast(instanceMap.get(klass)); } 

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

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

 Class> binderKlass = (Class>) (Class) FieldBinder.class; BinderAssociator.getInstance(Integer.class, binderKlass); 

RHSeeger,我得到了你原来的问题。 我找不到解决问题的方法。 您可以尝试使用的是MyMap类,它可以根据您的要求进行绑定。 但是,使用此地图会出现两个问题:

  1. 由于它被声明为MyMap ,因此无法向其添加具有给定类型的内容。 这是假的,我会向您推荐Java Generics常见问题解答 (参见案例研究3)以获取更多详细信息。
  2. 由于map具有键和值之间的连接,因此无法添加任何类型的两个独立对象(两个引用不同类型),因为这两种类型可能未连接。

在玩的时候我看到了一些错误,我无法解释。 我认为,一切都进入事实(正如我之前提到的)我们试图处理第二级参数化。

  class FieldBinder { static class MyMap extends HashMap, FieldBinder> { } static final MyMap instanceMap1 = new MyMap(); static final Map, FieldBinder> instanceMap2 = new HashMap, FieldBinder>(); public static  void test() { Class c1 = null; FieldBinder 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 } } 

您引用的示例告诉我,如何恢复对象的类型(类),同时需要恢复参数化的类型(类)。 这是不可能的。