Let's say I have Node
class that is part of a graph. Each Node
handles generic types T
and S
, so that we have Node<T, S>
. Each Node
can add inputs to itself from other Nodes via an addInput
method.
class Node<T, S> {
<T2, S2> void addInput(SomeUpdater<T2, S2> input) {
// processes input
}
}
One input Node
's T
becomes the receiver Node
's T2
in the addInput
method.
Now let's say I want to store the inputs of each Node, within the Node. So:
class Node<T, S> {
Map<String, NodeCache<T2, S2>> cache = new HashMap<>();
<T2, S2> void addInput(SomeUpdater<T2, S2> input) {
this.cache.put(thisIsOfTypeT2, thisIsOfTypeS2);
}
}
This doesn't work, because 1) T2
and S2
could be one of a handful of types, depending on which inputs are added, and the code above would require that all inputs have the same T2, S2
types; 2) I would have to add T2
and S2
to the Node
class, which I don't want to do.
Wildcards almost work fine:
class Node<T, S> {
Map<String, NodeCache<?, ?>> cache = new HashMap<>();
<T2, S2> void addInput(SomeUpdater<T2, S2> input) {
this.cache.put("a string", new NodeCache<T2, S2>()); // compiler is fine
this.cache.get("a string").get(thisIsOfTypeT2); // compiler nopes out of this one
}
}
On the second get
, I get method NodeCache.get(CAP#1) is not applicable (argument mismatch; T2 cannot be converted to CAP#1)
. I'm familiar with this great answer on wildcard generics, so generally I think wildcards may be out(?).
Alternatively, I could do something like Map<String, NodeCache<? extends SuperTypeA, ? extends SuperTypeB>> cache = new HashMap<>();
, but I run into the same problems. Ideally I'd even have Map<String, NodeCache<? extends SuperTypeA, ? extends SuperTypeA & SuperTypeB>>
, but I don't think Java even supports multiple bounded types for wildcards.
Not sure how to proceed from here, though. Any suggestions would be appreciated.