【问题标题】:Upperbound wild card上限通配符
【发布时间】:2015-03-18 04:35:16
【问题描述】:

我正在处理arraylist 中的上限通配符(?)。当我使用通配符声明一个数组列表时它不起作用。 例如 : 我有三个班级:

1) 人物类:

 public class Person {  
}

2) 扩展person的员工类:

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 类型的 add(capture#1-of ? extends Person) 方法不适用于参数(对象类型)。

但是从“?扩展人”类型的数组列表中,可以取“任何对象扩展人”,但为什么它不接受扩展的员工对象 人。

【问题讨论】:

    标签: java oop


    【解决方案1】:

    java 泛型是用 Erasure 的概念实现的,这意味着当您使用泛型时,任何特定的类型信息都会被删除。在泛型内部,您实际上正在使用 Object 例如 List (List ) 和 List (List ) 是相同的在运行时键入。泛型类型仅在静态类型检查期间出现,之后程序中的每个泛型类型都被擦除,通过将其替换为非泛型上限强>.

    由于擦除删除了类型信息,您可以为 unbounded 泛型参数 调用的方法只有 Object 的方法,但如果您可以限制它参数是类型的子集,那么您可以调用该子集中的方法。要执行此约束,java 泛型使用 extends 关键字。

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

    但是,当您说 ArrayList (? super Person) 时,您会说此列表包含派生自 Person 的特定对象,即基类或 超级类型 为 Person 的对象。因此,将 Person 或派生自 Person 的任何内容传递到此列表中是安全的。因此它起作用了。

    希望对您有所帮助!

    【讨论】:

      【解决方案2】:

      ArrayList&lt;? extends Person&gt; 可以是ArrayList&lt;Employee&gt;。在这种情况下,您将无法添加非员工。由于编译器不知道类型,它不允许你添加任何东西。

      请注意,编译器确实知道列表中已经存在的所有元素都是Person 的子类。所以get 工作,即使add 不工作:

        Person x = al.get(0);
      

      如果您想拥有可以采用您的三种类型中的任何一种的List,请使用ArrayList&lt;Person&gt;

      【讨论】:

      • 所以我们不应该使用“?”在左侧。
      • 仅当您不关心实际类型时。在这种情况下,你关心。 OTOH,如果您只想 get 来自 List 的东西,&lt;? extends Person&gt; 可以工作。
      • 奇怪的是 ArrayList正在工作。对于所有三个添加
      • 是的,super 适用于 add(但不适用于 get)。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-10-22
      • 2013-04-17
      • 1970-01-01
      • 1970-01-01
      • 2021-12-01
      • 1970-01-01
      相关资源
      最近更新 更多