泛型的概念
- 允许在定义类、接口时通过一个标识表示类中某个属性的类
型或者是某个方法的返回值及参数类型 - 泛型的好处:
保证如果程序在编译时没有发出警告,运行时就不会产生
ClassCastException异常;代码更加简洁、健壮;
集合中使用泛型
不使用泛型
- ArrayList添加的数据类型不一致时,会产生类型不安全问题;
- 强转时可能出现 java.lang.ClassCastException;
@Test
public void test1(){
ArrayList list=new ArrayList();
list.add(3);
list.add(5);
list.add(9);
list.add(3);
list.add("rtr");
for(Object object:list){
int a= (int) object;
System.out.println(a);
}
}
使用泛型
ArrayList使用泛型
@Test
public void test2() {
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(4);
list.add(5);
list.add(9);
for (Integer a : list) {
System.out.println(a);
}
Iterator<Integer> iterator = list.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}
HashMap使用泛型
@Test
public void test3() {
Map<String,Integer> map=new HashMap<String,Integer>();
map.put("reifne",23);
map.put("sophia",50);
map.put("Lucy",90);
map.put("Tom",6);
for (Integer value : map.values()) {
System.out.println(value);
}
Set<String> keySet = map.keySet();
Iterator<String> iterator = keySet.iterator();
while (iterator.hasNext()){
String key = iterator.next();
Integer value = map.get(key);
System.out.println(key+"----》"+value);
}
}
自定义泛型结构
- 泛型类可能有多个参数,应该将多个参数一起放在尖括号内:<E1,E2,E3>;
- 泛型不同类型的引入不能相互赋值。例如:ArrayList和ArrayList是两种类型不可以相互赋值;
- 泛型实例化的简化操作:ArrayList flist = new ArrayList<>();
- 泛型的指定中不能使用基本数据类型,可以用包装类代替;
- 静态方法不能使用类的泛型;
- 异常类不能是泛型的;
- 父类有泛型,子类可以选择保留泛型也可以选择指定泛型类型
自定义泛型类
public class Order<T> {
String ordername;
Integer orderId;
T orderAA;
public Order() {
}
public Order(String ordername, Integer orderId, T orderAA) {
this.ordername = ordername;
this.orderId = orderId;
this.orderAA = orderAA;
}
public String getOrdername() {
return ordername;
}
public void setOrdername(String ordername) {
this.ordername = ordername;
}
public Integer getOrderId() {
return orderId;
}
public void setOrderId(Integer orderId) {
this.orderId = orderId;
}
public T getOrderAA() {
return orderAA;
}
public void setOrderAA(T orderAA) {
this.orderAA = orderAA;
}
@Override
public String toString() {
return "Order{" +
"ordername='" + ordername + '\'' +
", orderId=" + orderId +
", orderAA=" + orderAA +
'}';
}
}
public class SubOrder extends Order<Integer> {
public SubOrder() {
}
public SubOrder(String ordername, Integer orderId, Integer orderAA) {
super(ordername, orderId, orderAA);
}
}
public class SubOrder1<T> extends Order<T>{
public SubOrder1(String ordername, Integer orderId, T orderAA) {
super(ordername, orderId, orderAA);
}
public SubOrder1() {
}
}
Order<String> order1 = new Order<>();
order1.setOrderAA("refine");
Order<String> order2 = new Order("pdd_computer_apple", 12547555, "pdd_computer_apple255333");
order2.setOrderAA("pdd_computer_apple25538883");
System.out.println(order2);
自定义泛型接口
自定义泛型方法
public <E> List<E> copyArrayToList(E[] arr){
ArrayList<E> list = new ArrayList<>();
for(E e:arr){
list.add(e);
}
return list;
}
Order<String> order = new Order<>();
Integer[] arr = {1, 3, 5, 7, 9};
List<Integer> list = order.copyArrayToList(arr);
System.out.println(list);
泛型在继承上的体现
- 如果Man是Person的一个子类型(子类或者子接口),而G是具有泛型声明的
类或接口,G<Man>并不是G<Person>的子类型!
List<Person> personList = null;
List<Man> manList = null;
通配符
通配符 ?
- 类A是类B的父类,G<A>和G<B>是没有关系的,二者共同的父类是:G<?>
- List<?>不能添加数据;
ArrayList<Object> list = new ArrayList<>();
ArrayList<String> list1 = new ArrayList<>();
ArrayList<Integer> list2 = new ArrayList<>();
ArrayList<?> list3 = new ArrayList<>();
list3=list;
list3=list1;
list3=list2;
ArrayList<?> list3 = new ArrayList<>();
list2.add(3);
list2.add(456);
list2.add(-965);
list3=list2;
System.out.println(list3.get(0));
for (Object i:list3){
System.out.println(i);
}
Iterator<?> iterator = list3.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
有限制条件的通配符的使用
? extends A
- 可以作为A以及它所有子类的父类;
- 不能作为A的父类的父类;
- 不可以添加数据;
- 可以读取数据;
? super A
- 可以作为A以及它所有父类的父类;
- 不能作为A的子类的父类;
List<? extends Person> extendsList = null;
List<? super Person> superList = null;
List<Student> list3 = new ArrayList<Student>();
List<Person> list4 = new ArrayList<Person>();
List<Object> list5 = new ArrayList<Object>();
extendsList=list3;
extendsList=list4;
superList=list4;
superList=list5;
- 可以添加数据;
- 可以读取数据(放入Object对象):
superList.add(new Student("refine"));
superList.add(new Person("lucy"));
Person person = extendsList.get(0);
System.out.println(person);
Object object = superList.get(1);
System.out.println(object);