上行外卡

时间:2015-03-18 04:35:16

标签: java oop

我正在使用arraylist中的上限外卡(?)。当我使用通配符声明一个arraylist时,它无法正常工作。 例如 : 我有三个班级:

1)人员类:

 public class Person {  
}

2)延伸人的员工类:

public class Employee extends Person {

}

3)扩展员工的部门课程。

public class Dept extends Employee{

}

现在我想要将这三个类的对象添加到一个单独的类中的arraylist中,如下所示。

public class TestPerson {
     public static void main(String[] args) {

     Person p1 =new  Person();
     Employee e1 = new Employee();
     Dept d1 = new Dept();
     ArrayList<? extends Person> al =new ArrayList<Person>();

     al.add(p1);
     al.add(e1);
     al.add(d1);


 }
}

代码中的最后三行显示以下错误: 在ArrayList类型中添加(capture#1-of?extends Person)的方法不适用于参数(对象类型)。

但是来自#34;类型的arraylist?延伸人&#34;,可以采取&#34;任何对象延伸人&#34; ,但为什么它不接受扩展的员工对象 人

2 个答案:

答案 0 :(得分:1)

ArrayList<? extends Person>可以是ArrayList<Employee>。在这种情况下,您将不被允许添加非员工。由于编译器不知道类型,因此它不允许您添加任何内容。

请注意,编译器 知道列表中已有的所有元素都是Person的子类。因此,即使get没有,add仍有效:

  Person x = al.get(0);

如果您想要List可以选择三种类型之一,请使用ArrayList<Person>

答案 1 :(得分:1)

java泛型使用 Erasure 的概念实现,这意味着当您使用泛型时,任何特定的类型信息都会被删除。在内部泛型中,您实际上使用的是对象,例如列表(列表&lt; String&gt;)和列表(列表&lt;整数&gt; )在运行时是相同类型的。泛型类型仅在静态类型检查期间出现,之后程序中的每个泛型类型都被擦除,将其替换为非泛型上限

由于删除只删除类型信息,您可以调用 无界泛型参数的方法是对象的方法,但如果您可以约束参数是类型的子集,然后您可以调用该子集中的方法。要执行此约束,java泛型使用 extends 关键字。

鉴于此背景,当您指定ArrayList(ArrayList&lt;?extends Person&gt;)时,您实际上是指“从Person继承的任何类型的列表”。这并不意味着该列表将包含任何类型的人。通配符(?)引用了明确的类型,因此它表示此列表未指定的某些特定类型(Person类型)将在列表中。因此,列表可以包含特定类型的人,但您不知道哪一个是那个。因此,您无法将此类型的对象添加到此列表中。

但是,当你说ArrayList(?super Person)时,你说这个列表包含派生自Person的特定对象,即基础或超类型为Person的对象。因此,将Person或派生自Person的任何内容传递到此列表中是安全的。因此它有效。

希望有所帮助!