简体   繁体   English

java泛型实例变量有界集合

[英]java generics instance variable bounded collection

I have below example of Java Generics where I am trying to store a processors map which can store a Processor of its object. 我在下面的Java泛型示例中尝试存储一个processors映射,该映射可以存储其对象的Processor I have added a generic type for the Processor class. 我为Processor类添加了通用类型。 I want restrict the map processors to store only the it's key class' Processor object as it's value. 我想限制地图processors只存储其键类的Processor对象作为其值。 Is there a way to use java wildcard or type bound on the processors collections? 有没有办法在processors集合上使用java通配符或类型绑定? Please note that the the map itself can store multiple object of different classes in the key. 请注意,地图本身可以在键中存储不同类的多个对象。

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) {
    }
}

As @LouisWasserman noted in his comment, you can't match the key and value types of a Map in java. 正如@LouisWasserman在评论中指出的那样,您无法在Java中匹配Map的键和值类型。

To implement this, you should use Object instead of wildcards for the key type in your map declaration: 要实现这一点,您应该在地图声明中使用Object而不是通配符作为键类型:

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

The compiler will now let you insert any key with any associated processor in the map. 现在,编译器将允许您在映射中插入具有任何关联处理器的任何键。 It's your job to only allow matching types to be inserted: 只允许插入匹配类型是您的工作:

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

To create the illusion of type-safety when reading from the map, you will need explicit casts; 要在从地图上读取时产生类型安全的错觉,您将需要显式强制转换; and perhaps some @SuppressWarning("unchecked") annotations. 以及一些@SuppressWarning("unchecked")注释。 Eg: 例如:

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

Create a ParamAndProcessor<T> class to hold the parameter and its Processor together: 创建一个ParamAndProcessor<T>类,以将参数及其Processor结合在一起:

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

  // Ctor.

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

Then store instances of this in the map: 然后将其实例存储在地图中:

Map<Object, ParamAndProcessor<?>> processors;

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

If you want to put anything into processors , it can't have ? 如果要在processors放入任何东西,它不会? as the key type. 作为密钥类型。

Note that your parameterizedMethod doesn't actually need to be parameterized. 注意,实际上不需要对您的parameterizedMethod进行参数化。 (Nor does the Processor class, at least for what you've shown). (至少对于您所显示的内容, Processor类也没有。)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM