泛型 -> 多态性 ->误解或它是如何工作的



让我们考虑代码块:

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

Ok:

  1. 据我所知,多态赋值不能在泛型中工作

    问题:但在行:2,3,4是否有列表,ArrayList, LinkedList不是通用的集合名称list ??

  2. 第4行不能编译,不管Date是否是Object的子类型

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

可以理解。请帮助。


还有一个问题:

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

输出:1

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

第一个问题:

所以规则是:子类可以做超类所能做的一切(也许更多)。

如果AB的子类,则

A<X>B<X>的子类

这是因为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,因此这也不会阻止不良内容的添加。

List是一个原始类型。对泛型类型List的引用应该是
参数化的

注意:

语句子类可以做父类所能做的一切是设计意图的一般语句,并不是字面上的真实。当然,你也可以找到反例。

据我所知,多态赋值不能在泛型中工作

实际上你在讨论泛型和继承。

如果你有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>的子节点

UPDATE:-如果您想将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
}

据我所知,多态赋值不能在泛型中工作

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

第4行不能编译,不管Date是Object的子类型

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

即使List List - raw类型,和ArrayList参数化类型

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

最新更新