当使用泛型或者接口时,传递的数据中,泛型类型不确定,可以通过通配符<?>表示。
但是一旦使用泛型的通配符后,只能使用Object类中的共性方法,集合元素自身方法无法使用。
1.通配符基本使用
泛型的通配符:不知道使用什么类型来接收的时候,此时可以使用?,?表示未知道配符。
此时只能接受数据,不能往该集合中存储数据。
泛型通配符:
?:代表任意的数据类型
使用方式:
不能创建对象使用
只能作为方法的参数使用
import java.util.ArrayList;
import java.util.Iterator;
public class Demo05Generic {
public static void main(String[] args) {
ArrayList<Integer> list1 = new ArrayList<>();
list1.add(1);
list1.add(2);
ArrayList<String> list2 = new ArrayList<>();
list2.add("A");
list2.add("C");
printArray(list1);
printArray(list2);
}
/*
定义一个方法,能遍历所有类型的ArrayList集合
这时我们不知道ArrayList集合使用什么数据类型,可以泛型的通配符?来接收数据类型
注意:
泛型没有继承概念的
*/
public static void printArray(ArrayList<?> list) {
//使用迭代器遍历集合
Iterator<?> it = list.iterator();
while(it.hasNext()){
//it.next()方法,取出的元素是Object,可以接收任意的数据类型
Object obj = it.next();
System.out.println(obj);
}
}
}
2.通配符高级使用——受限泛型
之前设置泛型的时候,实际上是可以任意设置的,只要是类就可以设置。但是在java的泛型
中可以指定一个泛型的上限和下限。
泛型的上限:
格式: 类名称<? extends 类> 对象名称
意义: 只能接收该类型及其子类
泛型的下限:
格式:类型名称<? super 类> 对象名称
意义:只能接收该类型及其父类型
比如:现已知Object类,String类,Number类,Integer类,其中Number是Integer的父类
泛型的上限限定:? extends E 代表使用的泛型只能是E类型的子类/本身
泛型的下限限定:? super E 代表使用的泛型只能是E类型的父类/本身
import java.util.ArrayList;
import java.util.Collection;
/*
泛型的上限限定:? extends E 代表使用的泛型只能是E类型的子类/本身
泛型的下限限定:? super E 代表使用的泛型只能是E类型的父类/本身
*/
public class Demo06Generic {
public static void main(String[] args) {
Collection<Integer> list1 = new ArrayList<Integer>();
Collection<String> list2 = new ArrayList<>();
Collection<Number> list3 = new ArrayList<>();
Collection<Object> list4 = new ArrayList<>();
getElemnet1(list1);
// getElemnet1(list2); //报错
getElemnet1(list3);
// getElemnet1(list4); //报错
// getElemnet2(list1); //报错
// getElemnet2(list2); //报错
getElemnet2(list3);
getElemnet2(list4);
/**
类与类之间的继承关系
Integer extends Number extends Object
String extends Object
*/
}
//泛型的上限:此时的泛型?,必须是Number类型或者是Number类型的子类
public static void getElemnet1(Collection<? extends Number> coll){
}
//泛型的下限:此时的泛型?,必须是Number类型或者是Number类型的父类
public static void getElemnet2(Collection<? super Number> coll){
}
}