7

I'm having a hard time trying to figure this out. Say I have the following code:

class Animal { }
class Mammal extends Animal { }
class Giraffe extends Mammal { }
...
public static List<? extends Mammal> getMammals() { return ...; }
...

public static void main(String[] args) {
    List<Mammal> mammals = getMammals(); // compilation error
}

Why does the assignment result in a compilation error? The error is something like:

Type mismatch: cannot convert from List<capture#4-of ? extends Mammal> to List<Mammal>

According to my understanding of covariance, the getMammals() method returns a list that will always contain Mammal objects so it should be assignable. What am I missing?

2 Answers 2

18

Because getMammals could return a List<Giraffe>, and if that was convertable to List<Mammal> then you'd be able to add a Zebra to it. You can't be allowed to add a Zebra to a list of Giraffe, can you?

class Zebra extends Mammal { }

List<Giraffe> giraffes = new List<Giraffe>();

List<Mammal> mammals = giraffes; // not allowed

mammals.add(new Zebra()); // would add a Zebra to a list of Giraffes
Sign up to request clarification or add additional context in comments.

Comments

6

Well, it doesn't work like that unfortunately.

When you declare getMammals() to return List<? extends Mammal> it means it can return List<Mammal> or List<Giraffe> but not List<Animal>

Yours main() should look like this:

public static void main(String[] args) {
    List<? extends Mammal> mammals = getMammals();
    Mammal mammal = mammals.get(0);
}

EDIT: Regarding covariance, that's what is usually meant by that:

class Animal {
    public Animal getAnimal() {return this;}
}

class Mammal extends Animal {
    public Mammal getAnimal() {return this;}
}

class Giraffe extends Mammal {
    public Giraffe getAnimal() {return this;}
}

As you can see it allows to overload return type of methods when you overriding the method.

4 Comments

+ 1, but could you explain what "List or List but not List" means?! :p
Reformatted to remove the confusing 'List or List but not List' :-)
The generics were being treated as html, escaped
I don't understand this answer - the OP doesn't want to treat it as a List<Animal>.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.