I've heavily simplified my problem. Here's how it reads.
I'm trying to figure out why the following code does not compile:
 List<AnonType<AnonType<?>>> l = new ArrayList<AnonType<AnonType<?>>>();
 l.add( new AnonType<AnonType<String>>() );
where
public class AnonType<T> {
  T a;
  List<T> b;
}
The compiler error is saying that add is not applicable for the argument given. OTOH, the following code with only 1-level nested wildcard compiles perfectly:
List<AnonType<?>> l = new ArrayList<AnonType<?>>();
l.add( new AnonType<String>() );
                The following compiles as expected:
    List<Set<? extends Set<?>>> list = new ArrayList<Set<? extends Set<?>>>();
    list.add(new HashSet<Set<String>>());
    list.add(new HashSet<Set<Integer>>());
The problem is that generics is type invariant.
Consider the simpler example:
Animal to Dog (e.g. Dog extends Animal)...
List<Animal> IS NOT a List<Dog>
List<? extends Animal> to a List<Dog>
Now here's what happens in this scenario:
Set<?> to Set<String>...
Set<Set<?>> IS NOT a Set<Set<String>>
Set<? extends Set<?>> to Set<Set<String>>
So if you want a List<T> where you can add a Set<Set<String>>, Set<Set<Integer>>, etc, then T is NOT Set<Set<?>>, but rather Set<? extends Set<?>>.
List<List<? extends Number>>List<Animal> animals = new ArrayList<Dog>()?<E extends Number> and <Number>?It doesn't compile because the type of the second argument in the Pair<,> of the statement is String and that type might not be the "unknown" type that was used in the declaration.  I think it will compile if you replace the ? with Object.  Of course, you will then lose compile-time type-checking.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With