让我们考虑代码块:
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:
据我所知,多态赋值不能在泛型中工作
问题:但在行:2,3,4是否有列表,ArrayList, LinkedList不是通用的集合名称
list
??第4行不能编译,不管Date是否是Object的子类型
问题:回到问题1,这是否意味着
Object
和Date
是多态性和泛型的情况?
可以理解。请帮助。
还有一个问题:
List list = new ArrayList<String>();
list.add(new Integer(1));
System.out.print(list.get(0));
输出:1
将编译,意味着没有类型安全。为什么?即使List list
是原始类型,ArrayList<String>
是参数化类型,任何方法都是无用的。为什么?
第一个问题:
所以规则是:子类可以做超类所能做的一切(也许更多)。
如果A
是B
的子类,则 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>
类型的引用的子类型(即使T
是E
的子类型)
即使List List - raw类型,和ArrayList参数化类型
声明了一个List
类型的引用。这在概念上与声明List<Object>
的引用类型相同。对任何方法(天气静态方法或实例方法)的调用在编译时使用引用类型解析。由于引用类型是List
(即原始列表),编译器将允许您向列表添加任何类型的对象。当编译类时,编译器将语句ArrayList<String>
转换为ArrayList
。这被称为type-erasure
。这也是为什么在运行时不会遇到任何问题的原因。