I have the next code:
class Cat extends Animal{}
List<Cat> oldCats = getCats();
List<Cat> newCats = doSomeWork(oldCats);
public static List<? extends Animal> doSomeWork(List<? extends Animal> animals){
List<? extends Animal> newAnimals = new ArrayList<>();
for(Animal a : animals){
newAnimals.add(a);
}
return newAnimals;
}
I have compilation error, that required type is not correct.
Required type:List<Cat>
Provided:List<capture of ? extends Animal>
How properly tune generics for List?
CodePudding user response:
public static List<? extends Animal> doSomeWork(List<? extends Animal> animals){
List<? extends Animal> newAnimals = new ArrayList<>();
Every time you use a ? extends Animal
, it means a different type of "something that is a subclass of Animal
". So, the type of the parameter, the type of the return value and the type of the local variable are different: you can't add things from animals
into newAnimals
(or vice versa), and you can't return either animals
or newAnimals
from the method.
Also, that return type isn't "List of a particular type of animal", it's "List of a particular but unknown type of animal". You can't get a List<Cat>
back from that, you can only ever get a List<? extends Animal>
.
If you want to indicate that they are the same, you need to declare a type variable, which you use in all of the declarations.
public static <T extends Animal> List<T> doSomeWork(List<T> animals){
List<T> newAnimals = new ArrayList<>();
This is still "some subclass of Animal
", but the fact they are all referred to by the T
means these are the same subclass; and the type that is returned is the same as the type you passed in.
CodePudding user response:
It looks like you want
public static <T extends Animal> List<T> doSomeWork(List<T> animals){
List<T> newAnimals = new ArrayList<>();
return newAnimals;
}
CodePudding user response:
Did it in such way:
public static <T extends Animal> List<T> doSomeWork(List<T> animals){
List<T> newAnimals = new ArrayList<>();
for (T a : animals){
Animal castedAnimal = (Animal)a;
newAnimals.add(a);
}
return newAnimals;
}
I don't like this casting... But it works