- ? super T: the compiler doesn't know a lot about the actual type, only that all instances of T match. Therefore you can add elements that are instances of T or a sub type. When you want to retrieve the compiler knows nothing so Object is the only possibility without casting
- ? extends T: this is just the other way around. The actual type is unknown so adding is not allowed. If T is Serializable, the actual type could be String, Integer, anything. Adding just any Serializable object is therefore not allowed. When you want to retrieve the compiler knows that no matter the type, everything IS-A T, so you can assign the elements to a reference of T without casting.
? is simply the same as "? extends Object".
Now these rules should allow you to choose what you want to return.
- Do you need to put anything in the outer map? Then "?" is not good for the key. The "?"s in the value are still allowed, because any Map is a Map<?,?>. If you don't need to put anything in the outer map then "?" is just fine.
- Do you need to put anything in the inner maps? Then "?" is not good for either the key or the value. If you don't need to put anything in the inner maps then "?" is just fine.