I am learning Java variance.
I am getting the Covariant to work but not Contravariance where I can accept a super type.
I have a simple class hierarchy for this:
Animal, Cat, Lion
Then I have two classes as Generic holders:
CovariantAnimalHolder ContraVariantHolder
The Covariant works fine but Contravariance isnt working.
Here is the code:
public class Animal {
private String name;
public Animal(String name) {
this.name = name;
}
public Animal() {
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
public class Cat extends Animal {
private boolean isWild;
public Cat(boolean isWild) {
this.isWild = isWild;
}
public Cat(){
}
public boolean isWild() {
return isWild;
}
public void setWild(boolean wild) {
isWild = wild;
}
}
public class Lion extends Cat{
private boolean isExtinct;
public Lion (boolean isExtinct) {
this.isExtinct = isExtinct;
}
public Lion () {
}
public boolean isExtinct() {
return isExtinct;
}
public void setExtinct(boolean extinct) {
isExtinct = extinct;
}
}
Animal Holders:
public class CovariantAnimalHolder<T extends Cat> {
private T animalHolder;
public T getAnimalHolder() {
return animalHolder;
}
public void setAnimalHolder(T animalHolder) {
this.animalHolder = animalHolder;
}
}
Main program:
So far great
public class VarianceMain {
public static void main(String[] args) {
//This works
CovariantAnimalHolder<Lion> lionCovariantAnimalHolder = new CovariantAnimalHolder<Lion>();
//This works:
CovariantAnimalHolder<Cat> catCovariantAnimalHolder = new CovariantAnimalHolder<>();
//This should not work, Perfect!
//CovariantAnimalHolder<Animal> animalCovariantAnimalHolder = new CovariantAnimalHolder<Animal>();
}
}
But when I create the ContraVariant holder I am getting some basic errors which I can't understand:
public class ContravariantAnimalHolder<T super Cat>{
private T animalHolder;
}
Error:
In Java, you cannot define a generic type as a covariant or contravariant, as you can in other languages, for example, in scala
Instead, in java, what you define are generic types with Upper bounds which limit you to the use of extends
when it comes to types, and you cannot use super
with generic types, reason you cannot use it in your ContravariantAnimalHolder
class.
You can, however define methods with lower bounded wildcards, which, depending on what you need may fit your needs for contravariant