Java-通过构造函数将泛型列表传递到类中

Java-通过构造函数将泛型列表传递到类中,java,generics,inheritance,polymorphism,Java,Generics,Inheritance,Polymorphism,我一直在尝试泛型和多态性。我遇到了一个我无法解决的问题 说我有 public abstract class Animal { private age; private weight; public Animal(){} public void Move(){ //stuff } public void Eat(){ //stuff } //Getters and setters } 然后 p

我一直在尝试泛型和多态性。我遇到了一个我无法解决的问题

说我有

public abstract class Animal {
    private age;
    private weight;

    public Animal(){}

    public void Move(){
        //stuff
    }

    public void Eat(){
        //stuff
    }

    //Getters and setters
}
然后

public Cat extends Animal {
    //Constructors
}

public Snake extends Animal {
    //Constructors
    public void ShedSkin(){
        //stuff
    }
}
我也有自己的类“MyAbstractClass”。就在这里,我似乎无法解决问题

public abstract class MyAbstractClass {
    private List<Animal> myAnimalList;

    public MyAbstractClass(){}

    public MyAbstractClass(List<? extends Animal> animalList) {
        this.myAnimalList = animalList;
    }

    public List<Animal> getAnimalList() {
        return myAnimalList;
    }

    //Stuff which DOES NOT add to the list
}

这对我不起作用。它在
公共MyAbstractClass(List处编译失败要使其正常工作,必须将MyAbstractClass中的字段从以下位置更改为:

private List<Animal> myAnimalList;
私有列表myAnimalList;


private List我刚刚用您的代码创建了一个项目。请更正以下错误

1) Import the java.util.List package.

2)  another error I find is this.. How don't know your requirement Cannot suggest the solution.

public MyAbstractClass(List<? extends Animal> animalList) {
        this.myAnimalList = animalList; <==== problem you cannot assign List<? extends Animal> to List<Animal> .. Subtyping is not allowed in generic class.
    }
1)导入java.util.List包。
2) 我发现的另一个错误是。。如果不知道您的需求,则无法提出解决方案。

公共MyAbstractClass(List嗯,您不能为MyAbstractClass分配
List添加泛型参数,这样您就可以知道列表中项目的类型。

您必须更改此项:
private
List myAnimalList to private List在MyAbstractClass的构造函数主体中,实际上只有一行代码需要更改。基本上,您有两个选择:强制转换传入列表或制作列表的(防御)副本

如果您只是保留对传入列表的引用,那么在代码之外对该列表所做的所有更改都将反映在MyAbstractClass中。这可能是您想要的,也可能不是您想要的。相反,您对MyAbstractClass中的列表所做的任何更改也将影响代码的调用者。这通常是出乎意料的。如果您打算添加到e list,强制转换传入列表的解决方案是危险的,因为您不知道传递给构造函数的列表元素的实际类型(调用方可能已将列表强制转换为
列表
,即使它确实是
列表
)-这不是类型安全操作,但不是禁止的。在构造函数内部强制转换也不是类型安全的,因此可能应该避免。不过,下面是具有强制转换的构造函数:

public MyAbstractClass(List<? extends Animal> animalList) {
    this.myAnimalList = (List)animalList;
}
您还应该将访问者更改为动物列表,除非每个调用者都可以修改动物列表:

public List<Animal> getAnimalList() 
    return Collections.unmodifiableList(myAnimalList);
}
这个解决方案的优点在于:(a)列表确实是不可变的(与Collections.unmodifiableList相比,Collections.unmodifiableList只是包装了一个可变列表)和(b)
ImmutableList.copyOf()
足够聪明,知道当它收到的列表是一个
ImmutableList
时,它不需要被复制。因为(a),
getAnimalList()
只需返回列表即可


顺便说一句:方法名的Java约定是以小写开头,例如shedSkin()而不是shedSkin()-这是C#约定。

如果我将myAnimalList字段更改为
privateList@JohnGeddes您的代码错误:private age;//没有字段type@JohnGeddes这就是问题所在吗?不,这不是问题。这是我试图实现的一个经过精心设计和简化的示例。
list这是一个基于我正在从事的项目要大得多。让MyAbstractClass获取猫的列表的问题是,据我所知,它无法被MyNakeClass扩展。我不希望在我的抽象类中创建新的ArrayList。不过我现在已经解决了。谢谢你的帮助!谢谢。我会尝试一下,很快回复你!Thanks这很管用,比我做的更好!是的,“泛型”是java“模板”的名字。虽然在实现级别上它们完全不同(在java中,它只是一个语法糖,在运行时丢失了),但从用户角度看,它们在功能上几乎是等价的。
private List<? extends Animal> myAnimalList;
public MyAbstractClass(List<Animal> animalList){
    // stuff
}
1) Import the java.util.List package.

2)  another error I find is this.. How don't know your requirement Cannot suggest the solution.

public MyAbstractClass(List<? extends Animal> animalList) {
        this.myAnimalList = animalList; <==== problem you cannot assign List<? extends Animal> to List<Animal> .. Subtyping is not allowed in generic class.
    }
public MyAbstractClass(List<? extends Animal> animalList) {

   myAnimalList= new ArrayList<Animal>();   

   for(Animal c: animalList){
        this.myAnimalList.add(c);
   }
}
public abstract class MyAbstractClass<T extends Animal> {
    private List<T> myAnimalList;
    public MyAbstractClass(List<T> animals) { myAnimalList = animals; }
    public List<T> getAnimalList() { return myAnimalList; }
    //etc.
}

public class MyCatClass extends MyAbstractClass<Cat> {
     public MyCatClass(List<Cat> cats) { super(cats); }
}
public class MySnakeClass extends MyAbstractClass<Snake> {
     public MySnakeClass(List<Snake> snakes) { super(snakes); }
     public ShedSkin() { getAnimalList().get(0).ShedSkin(); }
}
public List<Animal> getAnimalList() {
        return myAnimalList;
    } to
 public List<?extends Animal> getAnimalList() {
            return myAnimalList;
        }
public MyAbstractClass(List<? extends Animal> animalList) {
    this.myAnimalList = (List)animalList;
}
public MyAbstractClass(Collection<? extends Animal> animalList) {
    this.myAnimalList = new ArrayList<>(animalList);
}
public List<Animal> getAnimalList() 
    return Collections.unmodifiableList(myAnimalList);
}
public abstract class MyAbstractClass {
   private List<Animal> myAnimalList;

    public MyAbstractClass(){
        this(ImmutableList.of());
    }

    public MyAbstractClass(Collection<? extends Animal> animalList) {
        this.myAnimalList = ImmutableList.copyOf(animalList);
    }

    public List<Animal> getAnimalList() {
        return myAnimalList;
    }

    //Stuff which DOES NOT add to the list
}