泛型:
定义类、接口、方法的时候,同时声明了一个或者多个类型变量(如: <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> {
@Override
public void add(Teacher teacher) {
}
@Override
public ArrayList<Teacher> getByName(String name) {
return null;
}
}
StudentData实现接口类:
package cn.ensource.d10_generics_interface;
import java.util.ArrayList;
public class StudentData implements Data<Student> {
@Override
public void add(Student student) {
}
@Override
public 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等。