在Java中通过反射将元素添加到泛型列表

在Java中通过反射将元素添加到泛型列表,java,generics,Java,Generics,我试图为子类列表创建一个通用方法,无论我选择哪个子类,它都会添加一个新元素 为此,我举了一个容易理解的例子。 动物园里有一个装满长颈鹿和斑马的容器。斑马和长颈鹿都是动物。我需要创建一个“mate”方法,该方法将能够获得同基因类型的列表,即长颈鹿或斑马的列表(但不是两者都有),如果列表中有两种以上的动物,mate方法将向现有列表中添加另一种类型的动物(无需复制) 所以为了解决这个问题,我想使用反射,因为我不能在java中启动泛型类型(java中不允许使用它-不允许使用new T()。 因此,我创建

我试图为子类列表创建一个通用方法,无论我选择哪个子类,它都会添加一个新元素

为此,我举了一个容易理解的例子。 动物园里有一个装满长颈鹿和斑马的容器。斑马和长颈鹿都是动物。我需要创建一个“mate”方法,该方法将能够获得同基因类型的列表,即长颈鹿或斑马的列表(但不是两者都有),如果列表中有两种以上的动物,mate方法将向现有列表中添加另一种类型的动物(无需复制)

所以为了解决这个问题,我想使用反射,因为我不能在java中启动泛型类型(java中不允许使用它-不允许使用new T()。 因此,我创建了第一个元素的实例,并尝试使用
animals.add(newAnimal)将其添加到列表中。。但是,编译器对此表示不满,并出现以下错误:

Error: java: no suitable method found for add(Animal)
    method java.util.Collection.add(capture#1 of ? extends Animal) is not applicable
      (argument mismatch; Animal cannot be converted to capture#1 of ? extends Animal)
    method java.util.List.add(capture#1 of ? extends Animal) is not applicable
      (argument mismatch; Animal cannot be converted to capture#1 of ? extends Animal)
我通过在运行时再次使用反射获取add方法来解决这个问题,它正在工作(注释中的行),但是我想知道为什么编译器不允许我使用add for animal,因为我自己找不到答案

守则:

class Animal implements Comparable<Animal>{
    int numLegs;
    @Override
    public int compareTo(Animal o) {
        return this.numLegs-o.numLegs;
    }

}
class Giraffe extends Animal{
    int neckLength;
}
class Zebra extends Animal{
    int numOfStripes;
}
class Zoo{
    List<Giraffe> giraffes=new ArrayList<Giraffe>();
   List<Zebra> zebras=new ArrayList<Zebra>();
   public void printMostAnimals(){
       for(Animal a: getMostAnimals()){
           System.out.println(a);
       }
   }

    private List<? extends Animal> getMostAnimals() {
        if(giraffes.size()>zebras.size())
            return giraffes;
        return zebras;
    }

    public void mate(List<? extends Animal>animals) throws IllegalAccessException, InstantiationException {
       if(animals.size()>2){
           Class<?> firstAnimalInstanceClass=animals.get(0).getClass();

               Animal newAnimal=(Animal)firstAnimalInstanceClass.newInstance();
                animals.add(newAnimal);
              // animals.getClass().getDeclaredMethod("add",Object.class).invoke(animals,newAnimal);
               System.out.println("new mate was added");
               return;
       }
        System.out.println("no mate been added");
    }
}

class App{
    public static void main(String[] args) throws InstantiationException, IllegalAccessException {
        Zoo z=new Zoo();
        z.zebras.add(new Zebra());
        z.zebras.add(new Zebra());
        z.zebras.add(new Zebra());
        z.mate(z.zebras);
        System.out.println("new zebra been added?"+(z.zebras.size()>3));

    }
}
类动物{
int numLegs;
@凌驾
公共内部比较(动物o){
返回this.numLegs-o.numLegs;
}
}
长颈鹿类动物{
内领长度;
}
斑马类动物{
国际货币基金组织;
}
班级动物园{
列出长颈鹿=新的ArrayList();
List zebras=new ArrayList();
公共空白打印模板(){
对于(动物a:getMostAnimals()){
系统输出打印项次(a);
}
}
private List firstAnimalInstanceClass=animals.get(0.getClass();
Animal newAnimal=(Animal)firstAnimalInstanceClass.newInstance();
动物。添加(新动物);
//getClass().getDeclaredMethod(“add”,Object.class).invoke(animals,newAnimal);
System.out.println(“添加了新配偶”);
回来
}
System.out.println(“未添加配偶”);
}
}
类应用程序{
publicstaticvoidmain(字符串[]args)抛出instanceionException、IllegalAccessException{
动物园z=新动物园();
z、 斑马。添加(新斑马());
z、 斑马。添加(新斑马());
z、 斑马。添加(新斑马());
z、 交配(斑马);
System.out.println(“添加了新斑马?”+(z.zebras.size()>3));
}
}

谢谢,

您不能在
列表中添加除
null
以外的任何内容,因为有人可能会写:

List<Giraffe> giraffes = new ArrayList<>();
List<? extends Animal> animals = giraffes;
animals.add(new Zebra());

for (Giraffe g : giraffes) { // but there is a Zebra in there!
    g.eatLeavesFrom(tallTree); // Zebras can't do that!
}
List giraffes=new ArrayList();

列表不允许将动物“aa”添加到
列表中,因为“aa”可能是斑马


当您声明
List@AviadShiber,不,你不能。请给我一分钟时间更新答案,让它更清楚。谢谢,我现在明白了:)。因此,当我创建一个列表时,请尝试阅读一个名为类型擦除的主题。。但是语言的一致性。
List<Giraffe> giraffes = new ArrayList<>();
List<? extends Animal> animals = giraffes;
animals.add(new Zebra());

for (Giraffe g : giraffes) { // but there is a Zebra in there!
    g.eatLeavesFrom(tallTree); // Zebras can't do that!
}
class Animal<M extends Animal<M>> {
    M mate;
}

class Giraffe extends Animal<Giraffe> {}
class Zebra extends Animal<Zebra> {}
<A extends Animal<A>> void matingSeason(List<A> animals) {
    A x = null;
    for (A a : animals) {
        if (x != null) {
            a.mate = x;
            x.mate = a;
            x = null;
        } else {
            x = a;
        }
    }
}
((List)animals).add(newAnimal);
class AnimalList<AnimalType extends Animal> extends List<AnimalType> {
   void mate() {
      Class<AnimalType> firstAnimalInstanceClass = animals.get(0).getClass();
      AnimalType newAnimal = (AnimalType)firstAnimalInstanceClass.newInstance();
      add(newAnimal);
   }
}
AnimalList<Zebra>
AnimalList<Giraffe>
AnimalList<? extends Animal> list;
list.mate();