目录:
一、泛型概述及优势
二、泛型类
三、泛型方法
四、泛型接口
五、通配符和上下限
正文:
一、概述和优势
(1)概述:泛型是JDK5 中引用的特性,可以在编译阶段约束操作的数据类型,并进行检查
(2)格式:<数据类型>;注意:泛型只能支持引用数据类型
集合体系的全部接口和实现类都是支持泛型的使用的
package Genericity;
import java.util.ArrayList;
import java.util.List;
/**
* 目标:泛型的概述
*
* 什么是泛型?
* 泛型就是一个标签<数据类型>
* 泛型可以在编译阶段约束只能操作某种数据类型
*
*注意:
* JDK1.7开始之后后面的泛型声明可以省略不写
*
* 小结:
* 泛型就是一个标签
* 泛型可以在编译阶段约束只能操作某种数据类型
* 泛型只能支持引用数据类型
*/
public class Test {
public static void main(String[] args) {
List<String> list = new ArrayList<>();
list.add("Java1");
list.add("Java2");
List<String> list1 = new ArrayList();
list1.add("Java");
list1.add("Spring");
for (String s : list1) {
System.out.println(s);
}
List<Object> list2 = new ArrayList<>();
//存储任意类型的元素
list2.add("Java");
list2.add(false);
list2.add(22.3);
System.out.println(list2);
}
}
(3)优势:
1.统一数据类型
2.把运行时期的问题提前到了编译期间,避免了强制类型转换可能出现的异常,因为编译阶段类型就能够确定下来
二、泛型类
在类后的称为泛型类
概述:
泛型类的原理:
把出现泛型变量的地方全部替换成传输的真实数据类型
核心思想:
把出现泛型变量的地方全部替换成传输的真实数据类型
作用:
编译阶段约定操作的数据的类型,类似于集合的作用
package Genericity;
/**
* 定义泛型类
*/
public class MyArrayListTest {
public static void main(String[] args) {
//需求:模拟ArrayList 定义一个MyArrayList关注泛型设计
MyArrayList<String> list = new MyArrayList<>();
list.add("Java");
list.add("Java");
list.add("MySQL");
list.remove("MySQL");
System.out.println(list);//[Java, Java]
MyArrayList<Integer> list2 = new MyArrayList<>();
list2.add(23);
list2.add(25);
list2.add(27);
list2.remove(25);
System.out.println(list2);//[23, 27]
}
}
package Genericity;
import java.util.ArrayList;
public class MyArrayList<E> {
private ArrayList lists = new ArrayList();
public void add(E e){
lists.add(e);
}
public void remove(E e){
lists.remove(e);
}
@Override
public String toString() {
return lists.toString();
}
}
三、泛型方法
1、概述:
定义方法的同时定义了泛型的方法就是泛型方法
泛型方法的格式:修饰符<泛型变量>方法返回值 方法名称(形参列表){ }
范例: public <T>void show(T t){ }
作用:方法中可以使用泛型接收一切实际类型的参数,方法更具通用性
原理:把出现泛型变量的地方全部替换成传输的真实数据类型
例子:给任意一个类型的数组,都能返回它的内容。也就是实现Arrays.toString(数组)的功能
package Genericity;
/**
* 定义了泛型的方法就是泛型方法
*
* 泛型方法 的定义格式:
* 修饰符<泛型变量> 返回值类型 方法名(形参列表){
*
* }
* 注意:方法定义了是什么泛型变量,后面就只能用什么泛型变量
*
* 泛型类的核心思想,是把出现泛型变量的地方全部替换成传输的真是数据类型
*
* 需求:给你任意一个类型的数组,都能返回它的内容,Arrays.toString(数组)的功能
*
* 小结:
* 泛型方法可以让方法更灵活的接受数据,可以做通用技术
*/
public class method {
public static void main(String[] args) {
String[] names = {"小璐","蓉儿","小何"};
printArray(names);//[小璐, 蓉儿, 小何 ]
Integer[] ages = {10,20,30};
printArray(ages);//[10, 20, 30 ]
Integer[] ages2 = getArr(ages);
String[] names2 = getArr(names);
}
public static <T> T[] getArr(T[] arr){
return arr;
}
public static <T> void printArray(T[] arr){
if(arr != null){
StringBuilder sb = new StringBuilder("[");
for (int i = 0; i < arr.length; i++) {
sb.append(arr[i]).append(i == arr.length -1 ? " " : ", ");
}
sb.append("]");
System.out.println(sb);
}else{
System.out.println(arr);
}
}
}
核心思想:
把出现泛型变量的地方全部替换成传输的真实数据类型
作用:
方法中可以使用泛型接收一切实际类型的参数,方法更具通用性
四、泛型接口
概述:使用了泛型定义的接口就是泛型接口
格式:修饰符 interface 接口名称<泛型变量>{ }
范例:public interface Data<E>{ }
作用:泛型接口可以让实现类选择当前功能需要操作的数据类型
例子:教务系统,提供一个接口可约束一定要完成数据(老师,学生)的增删改查操作
原理:实现类可以在实现接口的时候传入自己操作的数据类型,这样重写的方法都将是针对于该 类型的操作。
package Genericity;
public class Teacher {
}
package Genericity;
public class Student {
}
package Genericity;
public interface Data<E> {
void add(E e);
void delete(int id);
void update(E e);
E queryById(int id);
}
package Genericity;
public class TeacherData implements Data<Teacher> {
@Override
public void add(Teacher teacher) {
}
@Override
public void delete(int id) {
}
@Override
public void update(Teacher teacher) {
}
@Override
public Teacher queryById(int id) {
return null;
}
}
package Genericity;
public class StudentData implements Data<Student> {
@Override
public void add(Student student) {
}
@Override
public void delete(int id) {
}
@Override
public void update(Student student) {
}
@Override
public Student queryById(int id) {
return null;
}
}
作用:
泛型接口可以约束实现类,实现类可以在实现接口的时候传入自己操作的数据类型这样重写的方法都将 是针对于该类型的操作
五、通配符和上下限
1.通配符
“ ?”可以在“使用泛型”的时候代表一切类型
E T K V 是定义泛型的时候使用的
例子:类似极品飞车游戏,所有的车都能一起参加比赛
package Genericity;
import java.util.ArrayList;
/**
* 通配符: ?
* ?可以在“使用泛型“的时候代表一切类型
*/
public class Demo {
public static void main(String[] args) {
ArrayList<BMW> bmws = new ArrayList<>();
bmws.add(new BMW());
bmws.add(new BMW());
bmws.add(new BMW());
go(bmws);
ArrayList<BENZ> benzs = new ArrayList<>();
benzs.add(new BENZ());
benzs.add(new BENZ());
benzs.add(new BENZ());
go(benzs);
//ArrayList<Dog> dogs = new ArrayList<>();
//dogs.add(new BENZ());
//dogs.add(new BENZ());
//dogs.add(new BENZ());
//go(dogs);
}
//
public static void go(ArrayList<? extends Car> cars){
}
}
class BENZ extends Car{
}
class BMW extends Car{
}
//
class Car{
}
NOTE:虽然BMW 和 BENZ 都继承了Car,但是ArrayList<BMW> 和 ArrayList<BENZ> 是没有关系的(以厕所为例,Car 是公厕,男女都能进。BMN是男厕,贴标签了;BENZ是女厕。是不一样的(ArrayList<BMW> 和 ArrayList<BENZ> ))
泛型的上下限:
?extends Car:?必须是Car或者其子类,泛型上限
?super Car:?必须是Car或者其父类,泛型下限
浏览到这的小伙伴记得给个一键三连啊(支持一下以父):点赞,收藏,关注!!!