泛型 - > Polimorphism - >误解或它是如何工作的

时间:2015-05-24 16:33:39

标签: java generics generic-list generic-programming

让我们考虑一下代码块:

List<List<Object>> list = new ArrayList();
list.add(new ArrayList<Object>); //Line 2
list.add(new LinkedList<Object>); //Line 3
list.add(new LinkedList<Date>); //Line 4

确定:

  1. 据我所知,polimorphic assigment不能在Generics中使用

    问题:但是在行中:2,3,4是否List,ArrayList,LinkedList对于名称为list的集合不是通用的?

  2. 第4行不会编译,无论Date是Object的子类型

    问题:回到问题1,这是否意味着ObjectDate是多态性和泛型的情况???

  3. 可以理解。请帮忙。

    还有一个问题:

    List list = new ArrayList<String>();
      list.add(new Integer(1));
      System.out.print(list.get(0));
    

    输出:1

    将编译,意味着没有类型安全。为什么?即使List list - 原始类型和ArrayList<String>参数化类型,任何方式都是无用的。为什么呢?

3 个答案:

答案 0 :(得分:1)

第一个问题:

所以规则是:一个子类可以做超类可以做的所有事情(可能还有更多)。

如果A<X>B<X>

的子类,则

AB的子类

这是因为A可以做B可以做的任何事情。无论您在何处使用B<X>,都可以使用A<X>

例如:

List<Object> lo
ArrayList<Object> alo

ArrayList<Object> alo可以执行List<Object> lo可以执行的所有操作,因此它是子类。

可是:

A<X>不是A<Y>的子类,即使X是Y的子类

这是因为A<X>无法执行A<Y>可以执行的所有操作。

以下情况:

List<Object> lo
List<Date> ld

List<Object> lo可以将任何对象添加到lo,但List<Date> ld只能添加日期,因此它不能成为子类。

第二个问题:

List list = new ArrayList<String>();
list.add(new Integer(1));

是的 - 这是非常糟糕的,并不起作用。这就是你收到警告的原因。

List声明是确定list类型以及您可以使用它做什么的重要部分。在运行时,由于称为类型擦除的东西,ArrayList<String>看起来只是ArrayList,因此也不会阻止添加不良内容。

  

列表是原始类型。对泛型类型列表的引用应为
  参数

CAVEAT:

语句子类可以执行超类可以执行的所有操作是设计意图的一般声明,而不是字面意义。当然,你可以找到反例。

答案 1 :(得分:0)

  

据我所知,polimorphic assigment不能在Generics中工作

那是错的。类型为ArrayList<E>的引用和类型为LinkedList<E>的引用都是类型为List<E>的引用的子类型。

  

无论Date是Object的子类型

,第4行都不会编译

LinkedList<T>类型的引用不是List<E>类型引用的子类型(即使TE的子类型)

  

即使列表列表 - 原始类型和ArrayList参数化类型

您声明类型为List的引用。这在概念上与声明List<Object>的引用类型相同。使用引用类型在编译时解析对任何方法(weather static或instance方法)的调用。由于引用类型是List(即原始列表),编译器将允许您将任何类型的对象添加到列表中。编译类时,编译器将语句ArrayList<String>转换为ArrayList。这称为type-erasure。这也是您在运行时不会遇到任何问题的原因。

答案 2 :(得分:0)

  

据我所知,polimorphic assigment不能在Generics中工作

其实你在谈论泛型和继承。

所以,如果您有List<Animal>,即动物名单,您可以在列表中添加任何动物,如猫,狗,但您无法将list of dog分配给list of animal

以下是示例

psvm{
List<Dog> list1 = new ArrayList<Dog>();
list1.add(new Dog());
method1(list1);// compilation error
}

public static void method1(List<Animal> list1) {
list1.add(cat); // Good
list1.add(dog); // Good
}

所以你没有在第2/3行遇到任何错误,但第4行会出现编译错误,因为new LinkedList<Date>不是List<Object>的孩子

更新: - 如果您想将list of dog分配给list of animal,请参阅下面

psvm{
List<Dog> list1 = new ArrayList<Dog>();
list1.add(new Dog());
method1(list1);// good
}

public static void method1(List<? extends Animal> list1) {
list1.add(cat); // compilation error
list1.add(dog); // compilation error
}