泛型:
定义类、接口、方法的时候,同时声明了一个或者多个类型变量(如: <E>),称之为泛型类、泛型接口、泛型方法,我们统称之为泛型。
说明这是一个泛型类。
如果不使用泛型,我们可以往ArrayList中传入各种对象,get方法返回的是Object类对象。
package cn.ensource.d8_generics;import java.util.ArrayList;public class Test {public static void main(String[] args) {// 目标:认识泛型ArrayList list = new ArrayList();list.add("a");list.add(123);list.add("黑马");Cat a = new Cat();list.add(a);for (int i = 0; i < list.size(); i++) {String res = (String) list.get(i); // 强转System.out.println(res);}}
}
强制类型转换会导致类型转换异常:
使用泛型类型为String类型,现在我给的是Cat对象,所以报错。
package cn.ensource.d8_generics;import java.util.ArrayList;public class Test {public static void main(String[] args) {// 目标:认识泛型
// ArrayList list = new ArrayList();
// list.add("a");
// list.add(123);
// list.add("黑马");
// Cat a = new Cat();
// list.add(a);
//
// for (int i = 0; i < list.size(); i++) {
// String res = (String) list.get(i); // 强转
// System.out.println(res);
// }System.out.println("-----------------------");ArrayList<String> list1 = new ArrayList<>(); // JDK1.7 开始,后面的数据类型可以不声明list1.add("Java1");list1.add("Java2");list1.add("Java3");list1.add("Java4");
// list1.add(new Cat());for (int i = 0; i < list1.size(); i++) {String res = list1.get(i);System.out.println(res);}}
}
作用:泛型提供了在编译阶段约束所能操作的数据类型,并自动进行检查的能力!这样可以避免强制类型转换,及其可能出现的异常。
泛型的本质:把具体的数据类型作为参数传给类型变量。
自定义泛型类:这就是C++的template
package cn.ensource.d9_generics_class;// 泛型类的定义
public class MyArrayList<E> {Object[] obj = new Object[10];private int size;public boolean add(E e) {arr[size++] = e;return true;}public E get(int index) {return (E) obj[index];}
}
多个类型变量:
package cn.ensource.d9_generics_class;public class MyArrayList2<E, T> {public void put(E e, T t) {}}
有继承约束关系的类型变量,后面只能定义Animal及其子类类型。
package cn.ensource.d9_generics_class;public class MyClass3<E extends Animal> {}
泛型接口:
Student类:
package cn.ensource.d10_generics_interface;public class Student {
}
Teacher类:
package cn.ensource.d10_generics_interface;public class Student {
}
Data泛型接口:
package cn.ensource.d10_generics_interface;import java.util.ArrayList;public interface Data<T> {void add(T t);ArrayList<T> getByName(String name);}
TeacherData实现接口类:
package cn.ensource.d10_generics_interface;import java.util.ArrayList;public class TeacherData implements Data<Teacher> {@Overridepublic void add(Teacher teacher) {}@Overridepublic ArrayList<Teacher> getByName(String name) {return null;}
}
StudentData实现接口类:
package cn.ensource.d10_generics_interface;import java.util.ArrayList;public class StudentData implements Data<Student> {@Overridepublic void add(Student student) {}@Overridepublic ArrayList<Student> getByName(String name) {return null;}
}
测试类:
package cn.ensource.d10_generics_interface;public class Test {public static void main(String[] args) {// 目标:掌握泛型接口的定义和使用// 场景:我们的系统需要处理学生和老师的数据,保存对象数据,根据名称查询数据}
}
注意:
类型变量建议是大写的英文字母,常用的有E/T/K/V等。