一、什么是泛型
泛型:标签;
中药店:药柜的标签,超市购物架上的标签;
是java5出现的,在之前是把集合元素类型设计为Object,之后用泛型限定集合的元素类型的。
(一)为什么要使用泛型:
1.通常我们程序员知道集合放入什么数据类型.应该限定类型;
2.在使用元素的时候,需要使用强制类型转换,很麻烦。
(二)换一种说法:
1、 提高安全性 — 将运行期的错误转换到编译器,尤其是在类型安全的问题上,当我们要操作的对象类型不符合泛型的要求时,就是编译错误,便于程序员在编译期就可以发现错误。
2、避免强转 — 比如我们在使用List时, 如果我们不使用泛型, 当从List中取出元素时, 其类型会是默认的Object, 我们必须将其向下转型为String才能使用,而使用泛型,就可以保证存入和取出的都是String类型, 不必在进行cast了,使代码具有更好的安全性和可读性。
(三) PS:泛型不止在java中广泛应用
百度百科:
泛型是程序设计语言的一种特性。允许程序员在强类型程序设计语言中编写代码时定义一些可变部分,那些部分在使用前必须作出指明。各种程序设计语言和其编译器、运行环境对泛型的支持均不一样。将类型参数化以达到代码复用提高软件开发工作效率的一种数据类型。
二、初识泛型-集合中的应用:
//在集合使用泛型之前的情况:
@Test
public void test1(){
ArrayList list = new ArrayList();
list.add(78);
list.add(76);
list.add(89);
list.add(88);
//问题一:类型不安全
list.add("Tom");
for (Object obj : list) {
//问题二:强制时,可能出现ClassCastException异常
int stuScore = (int) obj;
System.out.println(stuScore);
}
}
//在集合使用泛型之前的情况:
@Test
public void test2(){
ArrayList<Integer> list = new ArrayList<Integer>();
list.add(78);
list.add(76);
list.add(89);
list.add(88);
//报错,不能添加到添加了标签了的容器。编译时,就会进行类型检查,保证数据的安全。
//list.add("Tom");
//方式一
for (Integer obj : list) {
//避免了强转操作
int stuScore = obj;
System.out.println(stuScore);
}
//方式二
Iterator<Integer> iterator = list.iterator();
while (iterator.hasNext()) {
Integer integer = iterator.next();
System.out.println(integer);
}
}
在集合中使用泛型:
①集合接口或集合类在jdk5.0时都修改为带泛型的结构;
②在实例化集合类时,可以指明泛型类型。
③指明完以后,在集合类或借口时,内部结构使用到类的泛型的位置,都指定为实例化的泛型类型。
④注意点:泛型的类型是类,不能是基本数据类型。
⑤如果实例化是,没有指明默认为Obeject类型。
三、定义泛型
(一)定义泛型类:
demo
package com.sgh.generic;
/**
* 自定义的泛型类
* @author : sgh
* @description:TODO
* @date :2020/11/17 11:16
*/
public class Order<T> {
String name;
String orderId;
//类的内部结构就可以使用类的泛型
T orderT;
public Order(){
}
public Order(String name, String orderId, T orderT) {
this.name = name;
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{" +
"name='" + name + '\'' +
", orderId='" + orderId + '\'' +
", orderT=" + orderT +
'}';
}
}
(二)定义泛型方法:
如下:
/**
泛型方法:在方法中出现了泛型的结构,泛型参数与类的泛型参数没有任何关系。
换句话说,泛型方法所属的类是不是泛型类都没有关系
*/
public <E> List<E> copyFromArrayToList(E[] arr) {
ArrayList<E> list = new ArrayList<>();
for (E e : arr) {
}
return list;
}
泛型方法在调用时,指明泛型参数的类型。泛型方法是可以声明为静态的。
(三)泛型在继承上的体现
package com.sgh.generic;
/**
*此时SubOrder就只能是Integer类型,相当于“降级限制”了
* @author : sgh
* @description:TODO
* @date :2020/11/17 11:24
*/
public class SubOrder extends Order<Integer> {
}
第二种方式
package com.sgh.generic;
/**
* 把泛型的权限“完全”给子类
* @author : sgh
* @description:TODO
* @date :2020/11/17 11:28
*/
public class SubOrder1<T> extends Order<T> {
}
继承中还有很多其他情况,可根据实际情况分析。