2021-03-30

Java :: Generics :: Capture Wildcards

I have a couple of classes having identical methods, except with respect to certain parameter types:

interface ICls<T> {
    void doSomething(String key, T value);
    Map<String, T> getSomething();
}
class ClsA implements ICls<Boolean> {
    void doSomething(String key, boolean value) {}
    Map<String, boolean> getSomething() {}
}

class ClsB implements ICls<String> {
    void doSomething(String key, String value) {}
    Map<String, String> getSomething() {}
}

Now I'm trying to have a main class that stores a mixed list of these class objects and for each of these instances, passes info between its two methods:

class Main {
    List<ICls<?>> list = List.of(
        new ClsA(),
        new ClsB()
    );
    void run() {
        list.forEach(cls -> {
            Map<String, ?> data = cls.getSomething();
            data.keySet().forEach(key -> cls.doSomething(key, map.get(key));
        });
    }

The List<ICls<?>> and Map<String, ?> statements are OK. However, the map.get(key) throws an IDE error:

'doSomething(<String, capture<?>>) in '...ICls' cannot be applied to 'String, capture<?>'

Hovering the mouse cursor over the offending statement shows:

Required type: capture of ?
Provided: capture of ?

Assuming that I can't/don't want to change the generic type T to Object, and don't want to change the architecture either, what can I do to make the code here compile?

I've tried changing the signature of doSomething so that it accepts the entire Map<String, T> and call it like so, with no luck either:

cls.doSomething(cls.getSomething());


from Recent Questions - Stack Overflow https://ift.tt/2QPE8LX
https://ift.tt/eA8V8J

No comments:

Post a Comment