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.
