Skip to content

Can Functional Interfaces with generic type be stored in a static map?

I have used a static map to store a series of Functional Interfaces which associated with three classes A, B and C all inherited from a parent class. The code runs smoothly as follow:

private static final Map<Class<?>, BiConsumer> maps = Maps.newConcurrentMap();

@PostConstruct
public void init() {
    maps.put(A.class, BiConsumerA);
    maps.put(B.class, BiConsumerB);
    maps.put(C.class, BiConsumerC);
}

private static BiConsumer<A, String> BiComsumerA = (a, string) -> {//do something}
private static BiConsumer<B, String> BiComsumerB = (b, string) -> {//do something}
private static BiConsumer<C, String> BiComsumerC = (c, string) -> {//do something}

public static<T extends Parent> void exec(T t, String string) {
    maps.get(t.getClass()).accept(t, map);
}

However, there is a warning “Raw use of parameterized class ‘BiConsumer'” on the usage of Biconsumer in the static map. I tried various ways to add a parameterized type to ‘BiConsumer’ but unsuccessfully. Such as:

private static final Map<Class<?>, BiConsumer<?, String>> maps = Maps.newConcurrentMap();
private static final Map<Class<?>, BiConsumer<? extends Parent, String>> maps = Maps.newConcurrentMap();
private static final Map<Class<?>, BiConsumer<T, String>> maps = Maps.newConcurrentMap();
private static final Map<Class<?>, BiConsumer<T extends Parent, String>> maps = Maps.newConcurrentMap();

So my question is: Can Functional Interfaces with generic type be stored in a static map? If the answer is no, using Functional Interfaces directly, is it the only way to use Functional Interfaces in a static map? Are there more proper implementations? Thank you very much for any help.

Answer

Can Functional Interfaces with generic type be stored in a static map?

Yes, of course. List is easier for sake of demonstration:

private static List<Consumer<?>> listOfConsumers = new ArrayList<>();

@PostConstruct
public void init2() {
    Consumer<String> stringConsumer = str -> System.out.println(str);
    Consumer<Integer> intConsumer = i -> System.out.println(i);
        
    listOfConsumers.add(stringConsumer);
    listOfConsumers.add(intConsumer);
}

However, there is a warning “Raw use of parameterized class ‘BiConsumer'”

Just use a wildcard instead of a particular parameter.

private static final Map<Class<?>, BiConsumer<?, String>> maps = Maps.newConcurrentMap();