Let's say I have these classes : Vehicle, Car and Spaceship:
class Vehicle{
void rideVehicle(Vehicle v){
System.out.println("I am riding a vehicle!");
}
}
class Car extends Vehicle{
void rideVehicle(Vehicle c){
System.out.println("I am riding a car!");
}
}
class SpaceShip extends Vehicle{
void rideVehicle(Vehicle c){
System.out.println("I am riding a spaceship!");
}
}
and I write this method addCars:
private static void addCars(List<? extends Vehicle> vcls){
vcls.add(new Car());
vcls.add(new Car());
vcls.add(new Car());
}
Why do I get a compile time error?? I understand that List is a supertype of List for any X that extends Vehicle. right?
Thanks
Edit: the error I get (compile-time) : The method add(capture#2-of ? extends Vehicle) in the type List is not applicable for the arguments (Car).
Here's a pointer to why you're getting a compile error. Specifically,
Using prince get and put in wildcard If wildcard with Extends ---> Using get method If wildcard with Super ----> Using put method Here , you want to add value into List ( meaning put method) .You can change code
You can either use:
(which means the caller is to pass a list of objects that are Vehicle or a super type)
or
The supplied List is a list of some specific type of Vehicle (where, for the sake of argument we will refer to the type as
T
), but that specific typeT
is not known; it may beList<Vehicle>
,List<Car>
, etc. Therefore, since the specific generic type of the list is unknown, it is not permitted to invoke any method which requires the specificT
as an argument. Only methods which don't involveT
as an argument can be invoked.The practical upshot of this, in the case of List, is that this prevents anything being added to the list - the list is not writable. On the other hand, the list can be read, but with the returned objects only known as
Vehicle
.That is, the unknown type
T
cannot be supplied to the the List, but its known superclass ofVehicle
can be returned by the list.By way of example, given your method:
you could conceivably invoke:
which you intuit should be permitted. However, since
addCars
knows the list only as "some subtype ofVehicle
", it can't be allowed to add objects to the list since the following invocation would then be just as valid:whereby it becomes clear that it must be as mistake to try to add Car objects to a List under the guise of being a list of
Vehicle
objects.The type of parameter is
? extends Vehicle
, which means an unknown subtype ofVehicle
. Since we don’t know what type it is, we don’t know if it is a supertype ofCar
; it might or might not be such a supertype, so it isn’t safe to pass aCar
there.Read page 7 of this tutorial.
if following could be possible..
then you could call addCars in this way: