-
泛型的使用
-
- jdk 5.0 新增的特性
-
- 在集合中使用泛型:
-
注意:泛型的类型必须是类,不能是基本数据类型
-
如果实例化时,没有指明泛型的类型,默认类型为java.lang.Object
-
- 如何自定义泛型结构:泛型类,泛型接口,泛型方法
-
3.1 可以有多个参数。<E1,E2,E3>
-
3.2 泛型类的构造器没有尖括号。public GenericClass(){}
-
3.3 泛型类型不同的引用不能相互赋值。eg。不能把String集合赋值给Integer集合
-
3.4 静态方法不能用类的泛型
-
3.5 异常类不能是泛型的
-
3.6 不能使用new E[],但是可以:E[] elements=(E[])new Object[capacity];
-
3.7 泛型方法:在方法中出现了泛型的结构,泛型参数与类的泛型参数没有任何关系。
-
换句话说,泛型方法所属的类是不是泛型类都没有关系。
-
泛型方法可以声明为静态,原因:泛型参数是在调用方法时确定的,并非在实例化时确定
public class GenericTest {
//在集合中使用泛型之前的情况
@Test
public void test1(){
ArrayList list=new ArrayList();
list.add(78);
list.add(76);
list.add(88);
list.add(89);
//问题一:类型不安全
// list.add("Tom");
for (Object score:list){
//问题二:down casting 可能出现ClassCastException
int stuScore=(Integer)score;
System.out.println(stuScore);
}
}
//在集合中使用泛型的情况:以ArrayList为例
@Test
public void test2(){
ArrayList<Integer> list=new ArrayList<Integer>();
list.add(78);
list.add(76);
list.add(88);
list.add(89);
//编译时,会检查类型,保证数据安全
// list.add("Tom");
for(Integer score:list){
int stuScore=score;
System.out.println(stuScore);
}
Iterator<Integer> iterator = list.iterator();
while (iterator.hasNext()){
Integer next = iterator.next();
System.out.println(next);
}
}
@Test
public void test3(){
Map<String,Integer> map=new HashMap<String, Integer>();
map.put("Tom",87);
map.put("Jerry",87);
map.put("Jack",87);
//嵌套泛型
Set<Map.Entry<String,Integer>> entry=map.entrySet();
Iterator<Map.Entry<String, Integer>> iterator = entry.iterator();
while (iterator.hasNext()){
Map.Entry<String, Integer> e = iterator.next();
String key=e.getKey();
Integer value = e.getValue();
System.out.println(key+"===>"+value);
}
}
//泛型方法
public <E>List<E> copyFromArrayToList(E[] arr){
ArrayList<E> list=new ArrayList<>();
for (E e:arr){
list.add(e);
}
return list;
}
}
泛型在继承上的体现, 通配符的使用
-
- 泛型在继承方面的体现
-
类A是类B的父类,G<A>和G<B>不具备子父类关系,是并列关系
-
补充:类A是类B的父类,A<G>是B<G>的父类
-
- 通配符的使用
-
类A是类B的父类,G<A>和G<B>不具备子父类关系,是并列关系.
-
共同的父类是G<?>
public class GenericTest {
/*
* 1. 泛型在继承方面的体现
* */
@Test
public void test1(){
Object obj=null;
String str=null;
obj=str;
Object[]arr1=null;
String[]arr2=null;
arr1=arr2;
List<Object>list1=null;
List<String>list2=null;
// 此时的list1和list2的类型不具有子父类关系
// list1=list2;
}
/*
* 2. 通配符的使用---?
* */
@Test
public void test2(){
List<Object>list1=null;
List<String>list2=null;
List<?>list=null;
list=list1;
list=list2;
// print(list1);
// print(list2);
//
List<String>list3=new ArrayList<>();
list3.add("AA");
list3.add("BB");
list3.add("CC");
list=list3;
//添加:对于List<?>就不能向其内部添加数据,除了null
// list.add("DD");
//获取(读取):允许
Object o = list.get(0);
System.out.println(o);
}
public void print(List<?> list){
Iterator<?>iterator=list.iterator();
while (iterator.hasNext()){
Object obj=iterator.next();
System.out.println(obj);
}
}
/*
* 3. 有限制条件的通配符的使用
* ?extends A:
* G<? extends A>可以作为G<A>和G<B>的子类,其中B是A的子类
* ?super A:
* G<? super A>可以作为G<A>和G<B>的父类,其中B是A的子类
* */
@Test
public void test4(){
//相当于小于等于
List<? extends Person> list1=null;
//相当于大于等于
List<? super Person> list2=null;
List<Student> list3=new ArrayList<Student>();
List<Person> list4= new ArrayList<Person>();
List<Object> list5= new ArrayList<Object>();
list1=list3;
list1=list4;
// list1=list5;
// list2=list3;
list2=list4;
list2=list5;
//读取数据
list1=list3;
Person p=list1.get(0);
//编译不通过
// Student s=list1.get(0);
list2=list4;
Object obj=list2.get(0);
//写入数据
//编译不通过
// list1.add(new Student());
list2.add(new Person());
list2.add(new Student());
}
}