目录
1、什么是泛型
(1)在jdk1.5开始出现新特性,成为泛型 (2)使用泛型可以限定集合或者数组放什么类型数据,方法里面传递什么类型参数
2、演示泛型好处
(1)问题代码public class GenericDemo1 { public static void main(String[] args) { //如果参数是字符串 abc,转换int类型出现异常 java.lang.ClassCastException add("abc",2); } public static void add(Object m,Object n) { //Object 强转 int int m1 = (Integer) m; int n1 = (Integer)n; System.out.println(m1+n1); } }
(2)泛型解决问题 — <自定义类型1,自定义类型2> :使用大写字母代表自定义类型 <T,V> - <>可以写在类部分,写在方法部分public class GengricDemo2 { public static void main(String[] args) { CompareData<Integer> compareData1 = new CompareData<Integer>(1,2); CompareData<Double> compareData2 = new CompareData<Double>(1.1,2.3); } } //泛型类 class CompareData<T> { //定义T类型属性 private T a; private T b; //创建构造 public CompareData(T a,T b) { int a1 = (Integer)a; int b1 = (Integer)b; System.out.println(a1+b1); } }
3、泛型类和泛型接口
(1)泛型可以在类上面,或者接口上面使用 ** <类型变量列表>中的类型变量不能用于静态成员上。 【修饰符】 class 类名<类型变量列表>{ } public class User<T,V> {} 【修饰符】 interface 接口名<类型变量列表>{ } public interface IDao<T,A> {} (2)举例演示public class GengricDemo3 { public static void main(String[] args) { //语文老师 Student<String> student1 = new Student<String>("张无忌","优秀"); //数学老师 Student<Double> student2 = new Student<>("乔峰",60.1); //英语老师使用时: Student<Character> stu3 = new Student<Character>("张三", 'C'); } } class Student<T> { private String name; //姓名 private T score; //分数 public Student() { super(); } public Student(String name, T score) { super(); this.name = name; this.score = score; } public String getName() { return name; } public void setName(String name) { this.name = name; } public T getScore() { return score; } public void setScore(T score) { this.score = score; } @Override public String toString() { return "Student{" + "name='" + name + '\'' + ", score=" + score + '}'; } } interface IDao<T> { public void add(T name); } class IDaoClass implements IDao<Double> { @Override public void add(Double name) { } }
4、类型变量的上限
(1)语法: <类型变量 extends 上限> 表示含义:类型变量是上限或者上限的子类public class GenericDemo4 { public static void main(String[] args) { Stu<Integer> stu = new Stu<>(10); } } class Stu<T extends Integer> { private T score; public Stu(T score) { this.score = score; System.out.println(score); } }
5、泛型擦除
(1)泛型在编译时候出现,编译之后没有泛型这个东西了 处理机制是通过类型擦除,擦除规则: 若泛型类型没有指定具体类型,用Object作为原始类型; 若有限定类型< T exnteds XClass >,使用XClass作为原始类型; 若有多个限定< T exnteds XClass1 & XClass2 >,使用第一个边界类型XClass1作为原始类型;
6、泛型方法
(1)在方法上面使用泛型 【修饰符】 <类型变量列表> 返回值类型 方法名(【形参列表】)【throws 异常列表】{ //... } public static <T> void add(T a,T b) throws Exception {} (2)举例演示public class GenericDemo5 { public static void main(String[] args) { //getScore("优秀"); getScore(100); // getScore('A'); } public static <T extends Integer> void getScore(T score) { System.out.println(score); } }
6、类型通配符?
当我们声明一个方法时,某个形参的类型是一个参数化的泛型类或泛型接口类型, 但是在声明方法时,又不确定该泛型实际类型,我们可以考虑使用类型通配符public class GenericDemo6 { public static void main(String[] args) { //int类型 StudentInfo<Integer> s1 = new StudentInfo<>("lucy",100); //字符串 StudentInfo<String> s2 = new StudentInfo<>("mary","优秀"); //字符类型 StudentInfo<Character> s3 = new StudentInfo<>("jack",'B'); //把上面三种不同类型数据放到一个数组里面 //定义StudentInfo类型数组 泛型是通配符 ? StudentInfo<?>[] arr = new StudentInfo[3]; //向数组放值 arr[0]=s1; arr[1]=s2; arr[2]=s3; StudentInfoPrint.print(arr); } } class StudentInfoPrint { public static void print(StudentInfo<?>[] arr) { for (int i = 0; i < arr.length; i++) { System.out.println(arr[i]); } } } class StudentInfo<T>{ private String name; private T score; public StudentInfo() { super(); } public StudentInfo(String name, T score) { super(); this.name = name; this.score = score; } public String getName() { return name; } public void setName(String name) { this.name = name; } public T getScore() { return score; } public void setScore(T score) { this.score = score; } @Override public String toString() { return "姓名:" + name + ", 成绩:" + score; } }
7、类型通配符上限和下限
(1)上限 格式:<? extends E> ? 代表接收E类型或者E的子类型的元素 <? extends Number> (2)下限 格式:<? super E> ? 代表接收E类型或者E的父类型的元素 <? super String> * */