泛型
泛型指定对象中的某方法只能使用某些指定的数据类型。
用来指定集合中只能存放某一种数据类型(不能是基本数据类型,最起码也得是包装类)
一个小测试
ArrayList<Integer> list = new ArrayList<Integer>();
HashMap<String, Integer> map = new HashMap<String, Integer>();
map.put("泽丽", 100);
map.put("希维尔", 100);
map.put("卢锡安", 100);
//返回的是Set集合,其中因为泛型必须存储Map中的Entry,Entry因为泛型必须存储<String, Integer>类型的数据。
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();
System.out.println(e.getKey() + "--->" + e.getValue());
}
必须在类或接口的定义中加入对应的泛型结构,才可以在实例化的过程之使用泛型。
在实例化时使用泛型之后,其类中的对应方法也会根据泛型进行识别。
例如:add(E e) —> add(Integer e)
使用泛型可以省去判断A 是否instanceof B的判断了。
自定义泛型
示例:
public class Order<T> {
String name;
int OrderId;
T OrderT;
public Order() {
}
public Order(String name, int orderId, T orderT) {
this.name = name;
this.OrderId = orderId;
this.OrderT = orderT;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getOrderId() {
return OrderId;
}
public void setOrderId(int orderId) {
OrderId = orderId;
}
public T getOrderT() {
return OrderT;
}
public void setOrderT(T orderT) {
OrderT = orderT;
}
@Override
public String toString() {
return "Order{" +
"name='" + name + '\'' +
", OrderId=" + OrderId +
", OrderT=" + OrderT +
'}';
}
}
继承中的注意:
// 继承中泛型的使用,其子类不再是泛型类。
public class SubOrder extends Order<Integer>{
}
// 在创建对象时才声明泛型的泛型类的继承,子类仍然是泛型类
public class SubOrder1<T> extends Order<T>{
}
注:泛型不同的引用不能相互赋值
静态方法不能使用泛型
异常类不能使用泛型
new T[]是不合理的
泛型方法
泛型方法必须有泛型结构<>,且该结构与类定义的泛型参数无关,是新参数,泛型方法也不必在泛型类中。
在public后加入"<>"用于令编译器识别E为泛型结构而不是定义在其他位置的类结构。
public <E> List<E> copyFromArrayList(E[] arr){
ArrayList<E> list = new ArrayList<>();
for(E e : arr){
list.add(e);
}
return list;
}
其与类的泛型没有关系
泛型方法可以被声明为静态的
泛型也限制了继承中的类型转换(多态性被限制)
list<Object> listObject = null;
list<String> listString = null;
// listObject = listString; //这是不被允许的,泛型中不具备多态性
//上面这样赋值是使listObject的指针指向listString的区域,会使listObject.add()添加进去非String的元素。
通配符
当接收的参数类型不确定是,可以使用通配符 ‘?’
public void show(List<?> list){
Iterator<?> iterator = list.iterator();
while(iterator.hasNext()){
Object obj = iterator.next(); //由于类型未知,使用Object进行接收
System.out.println(obj);
}
}
使用通配符进行创造对象的话,对象无法写入,只能进行读取。
List<?> list = new ArrayList<>();
// list.add("AA"); //定义为通配符的对象不可以写入
带限制条件的通配符:
//? extends A 意思为list中存储的必须是A或A的子类对象
//? super A 意思为list中存储的必须是A或A的父类对象
List<? extends Object> list = new ArrayList<>();
List<? super Object> list1 = new ArrayList<>();