Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I thought I understood this but obviously not...

I have a method signature like so:

void doSomething(List<TypeA> typeAs){...}

List<TypeA<TypeB>> getTypeBTypeAs(){...}

but if I try and call

doSomething(getTypeBTypeAs());

I get a compile error: "the method doSomething(List) in the type ... is not applicable for the arguments (List>)"

however if i change the sig of doSomething to

void doSomething(List<TypeA<?>> typeAs){...}

it still doesn't work, but

void doSomething(List typeAs){...}

obviously it works as i bypass generics.

which seems odd.

Can someone fill me in?

Also, in this case I'd like doSomething to work with any List containing TypeAs of any generic type; undefined, TypeB, TypeC etc.

thanks.

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
153 views
Welcome To Ask or Share your Answers For Others

1 Answer

A generic class TypeA<TypeB> is a different type from TypeA. You can't pass in a parameter of type TypeA<TypeB> where the method expects a TypeA. Also TypeA<TypeB> is a different type from TypeA<TypeC>, so the same constraints apply.

The classic example (from Effective Java, 2nd Ed. AFAIR) is: we have containers for animals (Container<Animal>) and as subclasses of Animal we have Lion and Butterfly. Now, if you have a method

void func(Animal animal);

it will accept both lions and butterflies. However, this function

void func(Container<Animal> animalContainer);

will not accept a Container<Lion>, neither a Container<Butterfly>. Do realize that a strong cage useful for keeping lions safely would not stop butterflies from flying away, and vice versa a thick but light net to hold butterflies would not stand a chance against a lion.

If you really are sure that any kind of animal container suits you, declare your function like this:

void func(Container<? extends Animal> animalContainer);

Back to your case, I guess the only method to accept both List<TypeA> and List<TypeA<TypeB>> would be something like this:

void doSomething(List<?> list);

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share

548k questions

547k answers

4 comments

86.3k users

...