JavaSe—泛型
目录
1、认识泛型
2、泛型类
2.1 自定义泛型类
3、泛型接口
3.1 自定义泛型接口
4、泛型方法
5、通配符、上下限
6、泛型支持的类型
6.1 包装类
6.2 包装类具体的其他功能
1、认识泛型
- 定义类、接口、方法时、同时声明了一个或者多个类型变量(如:<E>)这样就被称为泛型类、泛型接口、泛型方法、它们统称为泛型。
- 作用:泛型提供了在编译阶段约束所能操作的数据类型,并自动进行检查的能力!
- 好处:这样可以避免强制类型转换,以及可能出现的异常。
- 泛型的本质:把具体的数据类型作为参数传给类型变量
代码1:认识泛型,搞清楚泛型的好处
GenericDemo1类
import java.util.ArrayList;public class GenericDemo1 {public static void main(String[] args) {//目标:认识泛型、搞清楚泛型的好处//不使用泛型,这时候可以存储任意数据类型//不使用泛型在接收数据的时候,可能会出问题,存储的数据类型不固定ArrayList list = new ArrayList();list.add("hello");list.add("world");list.add("java");list.add(1);//String s = list.get(0); //报错Object s = list.get(0); //不报错//使用泛型,在接收数据时,会保证数据的类型安全//使用<String>list1只能添加字符串,如果添加其他类型报错ArrayList<String> list1 = new ArrayList<>(); //在JDK7后后面尖括号可以省略不写list1.add("hello");list1.add("world");//list1.add(10);//报错String s1 = list1.get(0); //不报错}
}


2、泛型类
注意:类型变量建议用大写英文字母,常用的有E(一般代表数据类型)、T(一般代表返回值类型)、K、V(一般代表值类型)。
2.1 自定义泛型类
代码2:这里自定义了MyArrayList只是在学习泛型类的定义,并没有实现add等里面的方法。这里也可以给Java中的ArrayList包装给MyArrayList。包装设计模式
MyArrrayList类
public class MyArrrayList <E>{Object[] array = new Object[10];public boolean add(E e){ //添加元素return true;}
}
GenericDemo2 类:用来测试代码
public class GenericDemo2 {public static void main(String[] args) {//目标:自定义泛型类MyArrrayList list = new MyArrrayList();list.add(10);list.add("ll");MyArrrayList <String> list2 = new MyArrrayList<String>();list2.add("hello");//list2.add(11); //报错}
}
上面的代码使用了泛型后只能添加相应的类型,如果加其他类型报错,报错信息如下:

3、泛型接口
3.1 自定义泛型接口
代码3:简单自定义泛型接口里面的具体方法并没有实现
Student类
public class Student {
}
Teacher类
public class Teacher {
}
data接口
public interface data<T> {void add(T s); //添加元素void remove(T s); //删除元素
}
StudentData 类:接口的实现
public class StudentData implements data<Student>{@Overridepublic void add(Student s) {System.out.println("添加学生数据成功");}@Overridepublic void remove(Student s) {}
}
TeacherData 类
public class TeacherData implements data<Teacher> {@Overridepublic void add(Teacher s) {}@Overridepublic void remove(Teacher s) {}
}
enericDemo3类
public class GenericDemo3 {public static void main(String[] args) {//目标:搞清楚泛型接口的基本作用//需求:项目需要学生数据/老师数据都要进行增删改查操作StudentData s = new StudentData();s.add(new Student()); //添加学生数据TeacherData t = new TeacherData();t.add(new Teacher()); //添加老师数据}
}
4、泛型方法

代码4:
enericDemo4类
public class enericDemo4 {public static void main(String[] args) {//目标:学会定义泛型方法,搞清楚作用。//打印任意数组的内容Integer[] intArr = {1, 2 , 3, 4 , 5};printArr(intArr);Character [] CharArr = {'a','b','v'};printArr(CharArr);String[] name = {"1", "hhh", "你好"};printArr(name);}public static <E>void printArr(E []arr){int len = arr.length;for(int i = 0; i < len; i++){System.out.print(arr[i]+ " ");}System.out.println();}
}
/*
1 2 3 4 5
a b v
1 hhh 你好 */
5、通配符、上下限
- 就是“?”,可以在“使用泛型”的时候代表一切类型:E T K V 是在定义泛型的时候使用。
泛型上下限:
泛型上限: ?extends Car : ?能接收的必须是Car或者其子类。
泛型下限: ? super Car: ?能接收的必须是Car或者其父类。
代码5:下面的代码只是写了个框架来理解通配符以及泛型上下限。
Car类
//车类
//父类
public class Car {
}
XiaoMi类
public class XiaoMi extends Car{
}
BaoMa类
public class BaoMa extends Car{
}
Dog类
public class Dog {
}
enericDemo5:测试1
import java.util.ArrayList;public class enericDemo5 {public static void main(String[] args) {//理解通配符和上下限ArrayList<Car> list = new ArrayList<>();list.add(new BaoMa());list.add(new XiaoMi());go(list);}//开发一个方法表示车要比赛,这里可能不同类型的车比public static void go(ArrayList<Car> c){}
}
enericDemo6 类:测试2
import java.util.ArrayList;public class enericDemo6 {public static void main(String[] args) {ArrayList<XiaoMi> list = new ArrayList<>();list.add(new XiaoMi());list.add(new XiaoMi());go( list);ArrayList<BaoMa> list2 = new ArrayList<>();list2.add(new BaoMa());list2.add(new BaoMa());go( list2);ArrayList<Dog> list3 = new ArrayList<>();
// list3.add(new Dog());
// list3.add(new Dog());
// go(list3);}//如果这里要传入多种类型的参数//<>中写 XiaoMi,BaoMa、 Car 在调用时候都能会出问题//所以这里可以使用? 通配符<?>//表示这个方法可以接收任意类型的参数//那么问题来了,既然可以接收任意类型的参数。如果传入一个狗呢? 可以。但是狗没有不是Car,显然与现实不符//不能让狗和车比赛//所以引入了通配符的上限,下限public static void go(ArrayList<? extends Car> list){ //只有Car或者Car的子类才能调用这个方法}public static void go2(ArrayList<? super Car> list){ //只有Car或者Car的父类才能调用这个方法}public static void go3(ArrayList<?> list){ //任何类型都可以调用这个方法}public static void go4(ArrayList<XiaoMi> list){ //只有小米才能调用这个方法}public static void go5(ArrayList<BaoMa> list){ //只有宝马才能调用这个方法}//只有车才能调用这个方法 ,虽然XiaoMi和BaoMa都是Car的子类,但是ArrayList<XiaoMi> ArrayList<BaoMa>// 和 ArrayList<Car>没有关系的public static void go6(ArrayList<Car> list){ //只有车才能调用这个方法}
}
6、泛型支持的类型
- 泛型不支持基本数据类型,只能支持对象类型(引用数据类型)
- 为什么泛型不支持基本数据类型? 泛型擦除:泛型工作在编译阶段,等编译后泛型就没有论了,所以泛型在编译后会被擦除。所以类型会恢复成Object类型。
代码7:泛型不支持基本数据类型
enericDemo7
import java.util.ArrayList;public class enericDemo7 {public static void main(String[] args) {//目标:搞清楚泛型集合不支持基本数据类型ArrayList<int> list = new ArrayList<>(); //报错}
}
6.1 包装类
包装类就是把基本类型的数据包装成对象的类型。

enericDemo8
import java.util.ArrayList;public class enericDemo8 {public static void main(String[] args) {//包装类//手工包装Integer i = new Integer(10); //在JDk9 之后,被弃用Integer i1 = new Integer(10);System.out.println(i == i1);Integer i2 = Integer.valueOf(10);//推荐 -128 -127 之间的数字是被缓存的如果定义多个相同的变量,不会创建新的对象Integer i3 = Integer.valueOf(10);System.out.println(i2 == i3); // trueSystem.out.println(i == i3); //falseSystem.out.println("---------------自动装箱--------------");//自动包装、自动拆箱Integer i4 = 10;Integer i5 = 10;System.out.println(i4 == i5);Integer i6 = 128;Integer i7 = 128;System.out.println(i6 == i7);System.out.println("---------------自动拆箱--------------");//把包装类对象转换为对应的原始数据类型int i8 = i4;System.out.println(i8);ArrayList<Integer> list = new ArrayList<>();list.add(10); //自动装箱int i9 = list.get(0); //自动拆箱}
}
/*
false
true
false
---------------自动装箱--------------
true
false
---------------自动拆箱--------------
10*/
6.2 包装类具体的其他功能

代码9:
public class enericDemo9 {public static void main(String[] args) {//包装类的基本功能//把基本类型转为字符串//方法一int a = 10;String s = a + "";System.out.println(s);//方法二double b = 10.3;String str = Double.toString(b);System.out.println( str);//方法3:Integer i = new Integer(10);String s1 = i.toString();System.out.println(s1);System.out.println("------把字符串转化为真实类型------");//方法一String s2 = "10";int a1 = Integer.parseInt(s2);System.out.println(a1 + 1);//方法二String s3 = "10.1";double a2 = Double.valueOf(s3);System.out.println(a2 + 1);}
}
/*
10
10.3
10
------把字符串转化为真实类型------
11
11.1*/



