9、泛型
9.1 泛型概述
把容器元素的类型设计成一个参数,这个类型参数叫做泛型
-
JDK5 新增的特性,集合接口或集合类在JDK5时都修改为带泛型的结构
-
在实例化集合类时,可以指明具体的泛型类型
-
指明完后,在集合类或接口中凡是定义类或接口时,内部结构(如方法、构造器、属性等)使用到类的泛型的位置,都指定为实例化的泛型参数
-
泛型的类型必须是类,不能是基本数据类型,需要用到基本数据类型的位置用包装类替换
-
如果实例化时没有指明泛型的类型,默认类型为java.lang.Object类型
-
JDK7新特性:类型推断
List< Integer> list = new ArrayList<>();
9.2 自定义泛型
自定义泛型结构:泛型类、泛型接口、泛型方法
泛型类、接口
public class Order<T> {
String orderName;
int orderId;
//类的内部结构就可以使用类的泛型T
T orderT;
public Order(){};
public Order(String orderName,int orderId,T orderT){
orderName = orderName;
orderId = orderId;
orderT = orderT;
}
public T getOrderT(){
return orderT;
}
public void setOrderT(T orderT){
orderT = orderT;
}
}
如果定义了泛型类,实例化时没有指明类的泛型,则认为此泛型类型为Object类型
Order o = new Order();
o.setOrderT(123);
o.setOrderT("123");
要求:如果定义的类带泛型,建议在实例化时要指明类的泛型
Order<String> order = new Order<>("orderAA",1001,"order:AA");
order.setOrderT("describe");
子类在继承带泛型的父类时,
-
若指明泛型类型,则实例化子类对象时不再需要指明泛型
class subOrder extends Order< String >{ }
-
若没有指明泛型类型,则实例化子类对象时需要指明
class subOrder< T > extends Order< T >{ }
泛型方法
在方法中出现了泛型的结构,泛型参数与类的泛型参数没有任何关系
泛型方法所属的类是不是泛型类都没有关系
public <E> List<E> copyFromArrToList(E[] arr){
List<E> list = new ArrayList<>();
for(E e:arr){
list.add(e);
}
return list;
}
在泛型方法时指明泛型参数的类型
Integer[] arr = new Integer[]{1,2,3,4};
List<Integer> list = order.copyFromArrToList(arr);
总结:
- 泛型类不可声明为静态的,因为在只有在实例化泛型类创建对象时才可指明泛型类型
- 泛型方法可以声明为static静态的,原因:泛型参数是在调用类.方法时确定的,并非在实例化时确定
9.3 通配符
- 泛型在继承方面的体现
- 类A是类B的父类,G< A >和G< B >二者不具备子父类关系,二者是并列关系
- 类A是类B的父类,A< G >也是B< G >的父类,可以利用多态性
- 通配符:?
- 类A是类B的父类,G< A >和G< B >是没有关系的,二者共同的父类是:G< ? >
- 将G< A > 赋值给G< ? > g后,g就不能向其内部添加数据(除了null),但是允许读取数据,读取的数据类型为Object
- 有限制条件的通配符
- <? extends A>:G< ? extends A > 可以作为G< A >和 G< B >的父类,其中B是A的子类——【-∞,A】
- <? super A>:G< ? super A > 可以作为G< A >和 G< B >的父类,其中B是A的父类——【A,+∞】,可以赋值A及A的子类(多态)
- <? implements interface>:只允许泛型为实现了interface接口的实现类的引用调用
我的学习笔记有更多精彩内容哦
Java编程知识专栏