Reputation: 165
Why is it throwing compilation error at line 23. 'a' is an object of class Apple and col is a list containing Apple objects, but still, it is throwing a compilation error mentioned below:
The method add(capture#1-of ? extends Fruit) in the type Collection is not applicable for the arguments (Fruit)
public class Basket {
List<Fruit> list;
public Basket() {
list = new ArrayList<>();
}
public Basket(List<Fruit> plist) {
list = plist;
}
void addFruit(Collection<? extends Fruit> col) { // this does not work
// void addFruit(Collection<Fruit> col) { // this works
Fruit a = new Apple();
Apple a1 = new Apple();
Fruit f1 = new Fruit();
col.add(a);// line 23
}
int getSize() {
return list.size();
}
public static void main(String[] args) {
Fruit f1 = new Apple();
Fruit f2 = new Apple();
Fruit f3 = new Apple();
List<Fruit> list = new ArrayList<>();
list.add(f1);
list.add(f2);
list.add(f3);
Basket b = new Basket(list);
b.addFruit(list);
System.out.println(b.getSize());
}
}
class Fruit {
}
class Apple extends Fruit {
}
Upvotes: 2
Views: 1404
Reputation: 5546
A collection can only contain entries of some type and its subtypes. For example if you have a Collection<Banana>
, it can only contain bananas.
Even though Banana
is a sub-class of Fruit
, Collection<Banana>
is not type-compatible with Collection<Fruit>
. It might seem a bit counter-intuitive, but think of it this way: In a Collection<Banana>
you only expect a Banana
. You don't expect an Apple
. But if you have a Collection<Fruit>
, you can have all sorts of fruit in it. And you can add any fruit to the collection.
If you cast your Collection<Banana>
to Collection<Fruit>
, you can add apples in it. Then you try to pull a banana out of your Collection<Banana>
and you get an apple. Since you cannot cast Apple
to Banana
, a ClassCastException
is thrown at runtime and your code fails.
So, in your case, you probably want a Collection<Fruit>
as suggested by @Eran. However, to answer your question in detail: If you had a Collection<Banana>
, you could use the collection as Collection<? extends Fruit>
, but you are limited to methods that don't have generic input param.
For example you can mutate the collection using retainAll
, remove
and a few others, you can as well as use all read-only operations, but you can't add
new apples to your collection of bananas.
Upvotes: 0
Reputation: 393851
Collection<? extends Fruit> col
means that col
is a Collection
of Fruit
or a Collection
of some sub-class of Fruit
, such as Collection<Apple>
or Collection<Banana>
.
You can't add an Apple
to a Collection
that might be a Collection<Banana>
.
If you want to be able to add any Fruit
, change the signature to:
void addFruit(Collection<Fruit> col)
Upvotes: 6