java泛型实例变量有界集合

时间:2017-12-13 07:17:19

标签: java generics

我有以下Java Generics示例,其中我试图存储一个processors地图,该地图可以存储其Processor的对象。我为Processor类添加了一个泛型类型。我想限制地图processors只存储它的关键类'Processor对象作为它的值。有没有办法在processors集合上使用java通配符或类型绑定?请注意,地图本身可以在密钥中存储不同类的多个对象。

public class GenericsExample {

    private Map<?, Processor<?>> processors = new HashMap<>();

    public <O> void parameterisedMethod(O o) {
        processors.put(o, new Processor<O>());
    }

    static class Processor<T> {
        void process(T t) {
            System.out.println(t + " processed.");
        }
    }

    public static void main(String[] args) {
    }
}

2 个答案:

答案 0 :(得分:1)

@LouisWasserman在评论中指出,你无法匹配java中Map的键值和值类型。

要实现这一点,您应该使用Object代替通配符作为地图声明中的密钥类型:

private Map<Object, Processor<?>> processors = new HashMap<>();

编译器现在允许您在地图中插入任何关联处理器的任何键。只允许插入匹配类型是你的工作:

<T> void addProcessor(T instance, Processor<? super T> processor) {
    processors.put(instance, processor);
}

为了在从地图上阅读时创造出类型安全的错觉,你需要明确的演员阵容;也许还有一些@SuppressWarning("unchecked")注释。 E.g:

@SuppressWarnings("unchecked")
<T> Processor<T> getProcessor(T instance) {
    return (Processor<T>) processors.get(instance);
}

答案 1 :(得分:0)

创建一个ParamAndProcessor<T>类来保存参数及其处理器:

class ParamAndProcessor<T> {
  T param;
  Processor<T> processor;

  // Ctor.

  void process() {
    processor.process(param);
  }
}

然后在地图中存储此实例:

Map<Object, ParamAndProcessor<?>> processors;

public void parameterisedMethod(Object o) {
  processors.put(o, new Processor<>());
}

如果您想将任何内容放入processors,则不能将?作为密钥类型。

请注意,您的parameterizedMethod实际上并不需要参数化。 (Processor类也没有,至少对于你所展示的内容而言。