一、泛型特点
1、泛型提供了编译时类型安全检测机制,在编译时能检测到非法的类型。
2、集合如果没有指定泛型,就会默认为Object类型,为了避免遍历的时候出现类型转换异常,需要先判断类型,所以这样很麻烦。
3、有了泛型后,就实现设置了集合所存的数据类型,遍历集合时就不需要进行类型转换就可以直接遍历了。
4、泛型只能是引用类型,不能是基本数据类型,如int、double是不行的。
eg:
List<String> list = new ArrayList<String>();
二、泛型类
泛型类:
public class Student<T> {
private T stuNumber;
public T getStuNumber() {
return stuNumber;
}
public void setStuNumber(T stuNumber) {
this.stuNumber = stuNumber;
}
}
调用:
public class Test01 {
public static void main(String[] args) {
Student<String> student1 = new Student<String>();
student1.setStuNumber("10001");
System.out.println(student1.getStuNumber());
System.out.println("-----------------------");
Student<Integer> student2 = new Student<Integer>();
student2.setStuNumber(1);
System.out.println(student2.getStuNumber());
}
}
三、泛型方法
泛型方法:
public class Test02Domin {
public <T> void show(T t){
System.out.println(t);
}
}
调用:
public class Test02 {
public static void main(String[] args) {
Test02Domin test02Domin = new Test02Domin();
test02Domin.show("字符串类型");
test02Domin.show(111);
test02Domin.show(11.11);
test02Domin.show(false);
}
}
四、泛型接口
泛型接口:
public interface QizeInterface<T> {
T show(T t);
}
实现类:
public class QizeInterfaceImpl<T> implements QizeInterface<T>{
@Override
public T show(T t){
return t;
}
}
调用:
public class Test03 {
public static void main(String[] args) {
QizeInterfaceImpl<String> qize1 = new QizeInterfaceImpl<String>();
System.out.println(qize1.show("我是字符串"));
QizeInterfaceImpl<Integer> qize2 = new QizeInterfaceImpl<Integer>();
System.out.println(qize2.show(11));
QizeInterfaceImpl<Boolean> qize3 = new QizeInterfaceImpl<Boolean>();
System.out.println( qize3.show(false));
}
}
五、泛型接口与泛型方法融合使用
泛型接口、方向方法:
public interface QizeInterface<T> {
<M> T show(T t, M m);
}
实现类:
public class QizeInterfaceImpl<T> implements QizeInterface<T>{
@Override
public <M> T show(T t, M m) {
System.out.println(m);
return t;
}
}
调用:
public class Test03 {
public static void main(String[] args) {
QizeInterfaceImpl<String> qize1 = new QizeInterfaceImpl<String>();
System.out.println(qize1.show("我是字符串","ces"));
QizeInterfaceImpl<Integer> qize2 = new QizeInterfaceImpl<Integer>();
System.out.println(qize2.show(11,22));
QizeInterfaceImpl<Boolean> qize3 = new QizeInterfaceImpl<Boolean>();
System.out.println( qize3.show(false,true));
}
}
六、泛型通配符
- 概述
泛型通配符能够用于接收,表示可以接收所有的泛型类型;
泛型通配符不能用于添加。
eg:
public class Test01 {
public static void printList(List<?> list){
Iterator<?> iterator = list.iterator();
while (iterator.hasNext()){
System.out.println(iterator.next());
}
}
public static void main(String[] args) {
ArrayList<String> arrayListString = new ArrayList<>();
for (int i=0;i<5;i++){
arrayListString.add("i:"+i);
}
printList(arrayListString);
System.out.println("-------------------");
ArrayList<Integer> arrayListInteger = new ArrayList<>();
for (int i=0;i<5;i++){
arrayListInteger.add(i);
}
printList(arrayListInteger);
}
}
- 泛型通配符的上限
表示可以接收某类和其所有子类:
eg:
父类:
public class QizeParent {
}
子类:
public class Student extends QizeParent{
}
public class Test02 {
/**
* 泛型通配符上限
* List<? extends QizeParent> 上限
* 表示可以接收 QizeParent类和其所有子类
* @param list
*/
public static void printList(List<? extends QizeParent> list){
}
public static void main(String[] args) {
List<QizeParent> qizeParents = new ArrayList<>();
ArrayList<Student> students = new ArrayList<>();
printList(qizeParents);
printList(students);
}
}
- 泛型通配符的下限
表示可以接收某类和其所有父类:
eg:
父类:
public class QizeParent {
}
子类:
public class Student extends QizeParent{
}
public class Test02 {
/**
* 泛型通配符下限
* List<? super Student> 下限
* 表示可以接收 Student类和其所有父类
* @param list
*/
public static void printList(List<? super Student> list){
}
public static void main(String[] args) {
ArrayList<Student> students = new ArrayList<>();
List<QizeParent> qizeParents = new ArrayList<>();
printList(students);
printList(qizeParents);
}
}
- 可变参数(与泛型无关)
如int … a 为可变参数,底层是基于数组来实现的,表示传递的参数可变,底层封装成数组的形式传递给方法。
如果除了可变参数外还有其他的参数,则需要把可变参数放后面。
public class Test03 {
public static void main(String[] args) {
System.out.println("sum:"+sum(1,1));
System.out.println("sum:"+sum(2,2,2));
System.out.println("sum:"+sum(3,3,3,3));
System.out.println("sum:"+sum(4,4,4,4,4));
}
/**
* int ... a 为可变参数,底层是基于数组来实现的
* 表示传递的参数可变,底层封装成数组的形式传递给方法
* 如果除了可变参数外还有其他的参数,则需要把可变参数放后面
* @param c
* @param a
* @return
*/
public static int sum(int c, int ... a){
int sum = 0;
for (int i=0; i< a.length; i++){
sum += a[i];
}
return sum;
}
}
- 泛型的擦除机制
泛型原理底层会使用擦除机制,泛型是在编译阶段限制传递的类型,在编译后会擦除泛型。
将一个List集合 泛型 赋值给一个没有使用到泛型的list集合,直接去除泛型,这就是擦除机制。
public static void main(String[] args) {
List<String> strings = new ArrayList<>();
strings.add("qize");
//strings.add(1); //报错
//将一个List集合 泛型 赋值给一个没有使用到泛型的list集合,直接去除泛型
List list = strings;
list.add(1);
}