Martin Thoma
Martin Thoma

Reputation: 136605

Why can't I assign an instance with another type to a parameterized variable?

Why can't I do this:

LinkedList<Fruit> myFruits = new LinkedList<Apple>();

Error message:

Type mismatch: cannot convert from LinkedList<Apple> to LinkedList<Fruit>

Where is the difference to the following?

Fruit fruit = new Apple();

Upvotes: 2

Views: 114

Answers (4)

Peter Lawrey
Peter Lawrey

Reputation: 533660

A simple assignement is allowed because the reference is copied and the original is left untouched.

Apple apple = new Apple();
Fruit fruit = apple;
fruit = new Banana(); // apple is not touched and is still an Apple

whereas (AtomicReference to be a simple collection)

AtomicReference<Apple> apple = new AtomicReference<>(new Apple());
AtomicReference<Fruit> fruit = (AtomicReference) apple; // warning but compiles.
fruit.set(new Banana()); // this alters apple as well, making it invalid!
Apple apple2 = apple.get(); // throws ClassCastException.

Upvotes: 0

PermGenError
PermGenError

Reputation: 46428

Polymorphism simply doesn't apply to generic types.

LinkedList<Fruit> is not same as LinkedList<Apple> even though Fruit is a super class of Apple.

Refer to this Answer for the reason.

Upvotes: 1

Jon Skeet
Jon Skeet

Reputation: 1502086

Consider what you can do with a LinkedList<Fruit> - and think about what you'd want this code to do:

LinkedList<Apple> apples = new LinkedList<Apple>();
LinkedList<Fruit> fruits = apples;
fruits.add(new Banana());

Apple apple = apples.getFirst(); // Safe at compile time, but it's a Banana!

The conversion is the only place it makes sense for this to fail at compile-time. Now what you can write is:

LinkedList<? extends Fruit> myFruits = new LinkedList<Apple>();

... and then the compiler won't let you add anything to the list, as it doesn't know what the real element type is. Likewise you coudl write:

LinkedList<? super Apple> apples = new LinkedList<Fruit>();

Now you can add apples to the list, but you can't get apples out of the list, as again you don't know what the type would be.

Upvotes: 10

Aviram Segal
Aviram Segal

Reputation: 11120

Because then you could add an Orange to myFruits and that shouldn't work as the actual list is a list of Apple

For example (If you could make this);

List<Apple> myApples = new LinkedList<Apple>();
List<Fruit> myFruits = new LinkedList<Apple>();
myFruits.add(new Orange());

now myApples got an Orange in it

Upvotes: 0

Related Questions