Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Compile error with generics

There's the following class:

public class LivingBeing { … }

Then there's

public class Human extends LivingBeing { … }

Now there's also this wrapper:

public class LivingBeingWrapper<T extends LivingBeing> { … }

And to complete the picture there's also the method

public boolean validate(LivingBeingWrapper<LivingBeing> livingBeingWrapper)

Now when writing the following code

LivingBeingWrapper<Human> wrapper = createHumanWrapper();
validate(wrapper);

I get the following compile error:

The method validate(LivingBeingWrappe<LivingBeing> livingBeingWrapper) in the type MyType is not applicable for the arguments (LivingBeingWrapper<Human>).

But why? Human extends LivingBeing.


2 Answers

A banana is-a fruit. But a list of bananas is not a list of fruit. Otherwise you could take a list of bananas and add an apple (given that an apple is-a fruit).

That sounds rather gnomic, but it's key to what's happening above. You need to specify your wrapper such that it takes types extending LivingBeing.

For further info, see this article, and in particular the "Generics are not Covariant" section.

like image 50
Brian Agnew Avatar answered Apr 26 '26 08:04

Brian Agnew


Your validate method declares that it must be called with a LivingBeingWrapper parameterised with LivingBeing. However, you're passing in a LivingBeingWrapper parameterised with Human. Try changing your method declaration from this:

public boolean validate(LivingBeingWrapper<LivingBeing> livingBeingWrapper)

to this:

public boolean validate(LivingBeingWrapper<? extends LivingBeing> livingBeingWrapper)
like image 22
David Grant Avatar answered Apr 26 '26 08:04

David Grant