views:

65

answers:

3

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>() );
A: 

I suggest you step back a bit and try to do it in a slightly different way. I think if you tried using inheritance it would all become much clearer.

CSpangled
+1  A: 

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.

Steve Emmerson
A: 

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:

  • Given that there is a casting conversion from Animal to Dog (e.g. Dog extends Animal)...
    • A List<Animal> IS NOT a List<Dog>
  • There is a capture conversion from List<? extends Animal> to a List<Dog>

Now here's what happens in this scenario:

  • Given that there is a capture conversion from Set<?> to Set<String>...
    • A Set<Set<?>> IS NOT a Set<Set<String>>
  • There is a capture conversion from 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<?>>.

Related questions

See also

polygenelubricants
thank you, polygenelubricants. I was just reading your answer to the question you pointed as duplicate.
andigenu
@andigenu: Yes, there's more explanation there and in a few other questions linked, but I thought I should still answer it here for a more direct answer to this question.
polygenelubricants
@polygenelubricants: I appreciate it! I will also follow some of the links after I'm done with my current task, as I want to get a better grip of generics (which can be tricky).
andigenu