概念:
在定义类、接口时通过一个标识表示类中某个属性的类型或者是某个方法的返回值及参数类型。这个类型参数将在使用时(例如,继承或实现这个接口,用这个类型声明变量、创建对象时)确定(即传入实际的类型参数,也称为类型实参)
在集合中使用泛型
①集合接口或集合类在jdk5.0时都修改为带泛型的结构
②在实例化集合时,可以指明具体的泛型类型
③指明完以后,在集合类或接口中凡是定义类或接口时,内部结构使用到类的泛型的位置,都指定为实例化的泛型类型。
④泛型的类型必须是类,不能是基本数据类型。需要用到基本数据类型的位置,都需要使用对应的包装类。
⑤如果实例化时,没有指明泛型的类型。默认类型为java.lang.Object类型。
如何自定义泛型结构:泛型类、接口;方法
1、自定义泛型类、泛型接口
package com.collectionwork;
import org.junit.jupiter.api.Test;
public class Order <T> {
private String orderName;
private int orderId;
private T orderT;
public Order() {
}
public Order(String orderName, int orderId, T orderT) {
this.orderName = orderName;
this.orderId = orderId;
this.orderT = orderT;
}
public T getOrderT() {
return orderT;
}
public void setOrderT(T orderT) {
this.orderT = orderT;
}
@Override
public String toString() {
return "Order{" +
"orderName='" + orderName + '\'' +
", orderId=" + orderId +
", orderT=" + orderT +
'}';
}
}
class OrderTest{
@Test
public void test(){
Order<Integer> order = new Order("abc",11,12);
order.setOrderT(123);//如果定义了泛型类,在实例化是没有指明类的泛型,则默认泛型类型为Object类型
// order.setOrderT("abc");//如果定义的类是带泛型的,建议在实例化时指明类的类型
System.out.println(order.toString());
}
}
class OrderSon1<T> extends Order<T>{//仍然是泛型类
//子类在继承带泛型的父类时,没有指明泛型的类型,所以在实例化的时候需要指明泛型的类型
}
class OrderSon extends Order<Integer>{//不再是泛型类
//子类在继承带泛型的父类时,由于指明了泛型的类型,
// 所以子类在实例化时不再需要指明泛型类型
}
2、泛型方法
在方法中出现了泛型的结构,泛型参数与类的泛型参数没有任何关系。换句话说,泛型方法所属的类是不是泛型类都没有关系。
public class Method<S> {
public <E> List<E> copyFromArrayToList(E[] arr){
ArrayList<E> arrayList = new ArrayList<>();
for (E e: arr) {
arrayList.add(e);
}
return arrayList;
}
}
class MethodTest {
@Test
public void test(){
Method<String> method = new Method<String>();
Integer[] arr = new Integer[]{1,2,3,4};
List<Integer> list = method.copyFromArrayToList(arr);
System.out.println(list);
}
}
泛型方法可以声明为静态的。因为泛型参数是在调用方法时确实确定的,并非在实例化时确定的。
泛型在继承方面的体现
虽然类A是类B的父类,但是G< A > 和G< B > 二者并不具备子父类关系,二者是并列关系。A
通配符的使用
通配符:?
类A是类B的父类,G< A> 和G< B> 是没有任何关系的,二者的共同父类是:G<?>
有限制的通配符
? extends A: G<? extends A> 可以作为G< A> 和G< B >的父类,其中B是A的子类
?super A: G<? super A> 可以作为G< A> 和G< B>的父类,其中B是A的父类
泛型错误
1、不能 new (未知类型)E 泛型数组。
2、不能 new (未知类型)E 泛型对象。
3、泛型方法中不能使用泛型类中定义的泛型参数。