泛型的使用和在继承方面的注意事项
@[toc]
1、泛型在继承方面的体现
基本知识
- 如果B是A的一个子类型(子类或者子接口),而G是具有泛型声明的 类或接口,G < B > 并不是G < A > 的子类型!
比如:String是Object的子类,但是List并不是List 的子类。
- 类A是类B的父类,G < A > 和G < B > 二者不具备子父类关系,是并列关系
代码举例
public class java1 {
//1.泛型在继承方面的体现
@Test
public void test1() {
//类
Object obj = null;
String str = null;
obj = str;//可以把子类的对象赋给父类的引用,多态的体现
//数组
Object[] objects = null;
String[] strings = null;
objects = strings;
List<Object> list1=null;
List<String> list2=null;
// list1=list2;//不可以,
//原因:此时的list1和list2的类型不具有子父类的关系
}
}
补充:类A是类B的父类(或者接口),A是B的父类
2、通配符的使用
通配符:?
类A是类B的父类,G < A > 和G < B > 二者不具备子父类关系,二者的共同父类是:G < ? >
- 使用类型通配符:?
- 比如:List<?> ,Map<?,?>
- List<?>是List、List等各种泛型List的父类。
- 读取List的对象list中的元素时,永远是安全的,因为不管list的真实类型是什么,它包含的都是Object。
- 写入list中的元素时,不行。因为我们不知道c的元素类型,我们不能向其中 添加对象。(唯一的例外是null,它是所有类型的成员)
使用通配符后数据的读取和使用要求代码举例
@Test
public void test2() {
List<Object> list1=null;
List<String> list2=null;
List<?> list=null;
list=list1;//list1和list2都可以赋值给list
list=list2;
List<String> list3 = new ArrayList<>();
list3.add("123");
list3.add("456");
list3.add("789");
list=list3;
//list添加操作:不能向其内部添加数据,除了添加null以外
// list.add();
list.add(null);
//读取:允许读取数据
Object o = list.get(0);
System.out.println(o);
}
3、通配符的使用:有限制的通配符
代码举例:
@Test
public void test3(){
List<? extends Person> list1=null;
List<? super Person> list2=null;
List<Student> list3=null;
List<Person> list4=null;
List<Object> list5=null;
list1=list3;
list1=list4;
//list1=list5;//不允许,因为?可以是Person的子类,可以就是Person,但是肯定不会是Person的父类Object
//list2=list3;//不允许
list2=list4;
list2=list5;
}
类,可以就是Person,但是肯定不会是Person的父类Object
//list2=list3;//不允许
list2=list4;
list2=list5;
}