是否可以绑定嵌套泛型?

时间:2010-04-06 08:36:16

标签: java generics capture

是否可以将嵌套的泛型/捕获绑定在一起?

我经常遇到将类的Map查找到所述类的泛化项的问题。具体来说,我想要这样的东西(不,T不会在任何地方声明)。

private Map<Class<T>, ServiceLoader<T>> loaders = Maps.newHashMap();

简而言之,我希望loaders.put / get具有类似这样的语义:

<T> ServiceLoader<T> get(Class<T> klass) {...}
<T> void put(Class<T> klass, ServiceLoader<T> loader) {...}

以下是我能做的最好的事情吗?我是否必须忍受不可避免的@SuppressWarnings("unchecked")某个地方?

private Map<Class<?>, ServiceLoader<?>> loaders = Maps.newHashMap();

2 个答案:

答案 0 :(得分:6)

让我看看如果我有你的意图:你想要一张存储成对Class / ServiceLoader的地图,其中每对由同一T参数化,但是{{1}两对可能有所不同吗?

如果是这种情况,那么最好的解决方案是声明自己的类,它将展示这样的接口。在内部,它会将这些对存储在通用的T地图中。

Map<Class<?>,ServiceLoader<?>>

public class MyMap { private Map<Class<?>, ServiceLoader<?>> loaders = new HashMaps<Class<?>, ServiceLoader<?>>(); public<T> void put(Class<T> key, ServiceLoader<T> value) { loaders.put(key, value); } @SuppressWarnings("unchecked") public<T> T get(Class<T> key) { return (ServiceLoader<T>) loaders.get(key); } } 注释不是纯粹的邪恶。您应该尽量避免使用它们,但在某些情况下您可以确定转换是正确的,尽管编译器无法看到它。

答案 1 :(得分:0)

我的建议是为这种情况创建一个新的Object。我发现您使用的是Maps.newHashMap(),所以我认为您使用了Google Guava,因此我会使用ForwardingMap

public class Loader<T> extends ForwardingMap<Class<T>, ServiceLoader<T>> {

   private Map<Class<T>, ServiceLoader<T>> delegate = Maps.newHashMap();

}

一个简单的测试证明我的建议是有效的:

public class Loader<T> extends ForwardingMap<Class<T>, Class<T>> {

   private Map<Class<T>, Class<T>> delegate = Maps.newHashMap();

   @Override protected Map<Class<T>, Class<T>> delegate() {
      return delegate;
   }

   public static void main(String[] args) {
      Loader<Integer> l = new Loader<Integer>();

      l.put(Integer.class, Integer.class);

      // error
      l.put(Integer.class, String.class);
   }

}