开发者

multiple nested wildcard - arguments not applicable [duplicate]

开发者 https://www.devze.com 2023-01-15 13:56 出处:网络
This question already has answers here: Can't cast to to unspecific nested type with generics (5 answers)
This question already has answers here: Can't cast to to unspecific nested type with generics (5 answers) Closed 8 years ago.

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 onl开发者_开发问答y 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:

  • 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

  • Can't cast to to unspecific nested type with generics
  • Multiple wildcards on a generic methods makes Java compiler (and me!) very confused
  • Java Generic List<List<? extends Number>>
  • Any simple way to explain why I cannot do List<Animal> animals = new ArrayList<Dog>()?
  • What is the difference between <E extends Number> and <Number>?

See also

  • Java Generics Tutorial
    • Generics and Subtyping | Wildcards | More Fun with Wildcards
  • Angelika Langer's Java Generics FAQ
    • What is a bounded wildcard?
    • Which super-subtype relationships exist among instantiations of generic types?


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.

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号