java - 如何在异构映射中使用泛型?

标签 java generics concurrency java.util.concurrent concurrenthashmap

我有一个实用方法来帮助使用 ConcurrentMap.putIfAbsent,如下所示:

public static <K, V> V putIfAbsent(
        ConcurrentMap<K, V> map, K key, Callable<V> task) {
    try {
        V result = map.get(key);
        if (result == null) {
            V value = task.call();
            result = map.putIfAbsent(key, value);
            if (result == null) {
                result = value;
            }
        }
        return result;
    } catch (Exception ex) {
        throw new RuntimeException(ex);
    }
}

现在我必须处理这样一个异构 map :

private ConcurrentMap<Class<?>, List<ClassHandler<?>>> handlerMap;

以及向其添加处理程序的方法:

public <T> void addHandler(Class<T> c, ClassHandler<? super T> handler) {
    putIfAbsent(handlerMap, c, new Callable<List<ClassHandler<?>>>() {
        @Override
        public List<ClassHandler<?>> call() throws Exception {
            return new CopyOnWriteArrayList<>();
        }
    }).add(handler);
}

到目前为止一切都很好,但是当我尝试处理一个类时问题就出现了,例如:

Class<String> c = String.class;
List<ClassHandler<?>> handlers = handlerMap.get(c);
if (handlers != null) {
    for (ClassHandler<?> c : handlers) {
        handler.handle(c);
    }
}

但是,此代码无法编译:

error: method handle in class ClassHandler<T> cannot be applied to given types;
        handler.handle(c);
  required: Class<CAP#1>
  found: Class<String>
  reason: actual argument Class<String> cannot be converted to Class<CAP#1> by method invocation conversion
  where T is a type-variable:
    T extends Object declared in class ClassHandler
  where CAP#1 is a fresh type-variable:
    CAP#1 extends Object from capture of ?
1 error

如果我使用handler.handle((Class) c),代码可以编译,但我会收到未经检查的警告。虽然我可以添加 @SuppressWarnings("unchecked") 注释,但如果没有更好的方法,这将是最后的选择。

关于这个问题有什么想法吗?

最佳答案

对。映射本身的类型并不能保证类的类型参数和相应的类处理程序相同。 (无论如何,没有类型可以表达这一点。)但是,您正确地使用了自己的 add 方法来确保它们在放入时匹配。因此可以相信它们是相同的。在这种情况下,只需将处理程序转换为适当参数化的类型(您将需要抑制警告):

for (ClassHandler<?> handler : handlers) {
    ((ClassHandler<String>)handler).handle(c);
}

关于java - 如何在异构映射中使用泛型?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11983067/

相关文章:

java - 更改需要声明为final的局部变量的值

并行类层次结构上下文中的 Java 泛型问题

java - 在扩展 Enum 的泛型类中使用 Enum.values

.net - 使用字典时 .NET 4 并发性能差

java - 如何在 Java 中使用 ThreadPoolExecutor 处理 RejectedExecutionException

java - 追加到数组与写入文件

java - 使用已配置的 JAAS 主题来验证 HttpURLConnection?

java - 无法解决双向链表的indexOf函数

c# - 生成某个给定类型的通用列表

c# - 寻找一种允许一个编写器并拒绝其他编写器的框架类