一:认识泛型
1.定义类,接口,方法时,同时声明了一个或者多个类型变量(如:<E>),称为泛型类,泛型接口,泛型方法,它们统称为泛型。
如果并没有在<>内限制数据类型 那么它默认就是object类。
如果限制了数据类型则只能添加相对应类型的变量。注意:<>内只能添加引用数据类型 不能添加基本数据类型。
2.作用:泛型提供了在编译阶段约束所能操作的数据类型,并自动进行检查的能力!这样可以避免强制类型转换,及其可能出现的异常。
3.泛型的本质:把具体的数据类型作为参数传给类型变量。
二:自定义泛型类
1.正常单个数据类型 相当于ArrayList集合 和其作用相似。
public class A<E> {
public Object[] arr = new Object[10];//设置一个数组来储存添加的数据
public int size;//记录当前数据的位置
public boolean add(E e){
arr[size++] = e;//对当前位置的数组进行赋值
return true;
}
public E get(int index){
return (E)arr[index];//得到索引位置的数据
}
}
2.多个数据类型 可以声明多个类型变量。
public class B<M, N> {
public boolean put(M m, N n){
return true;
}
}
3.继承型数据类型 <>内数据类必须要是继承于或等于指定的类才不报错。
public class C<A extends Animal> {}
public class Dog extends Animal{}
public class Cat extends Animal{}
C<Cat> c = new C();
C<Dog> c2 = new C();
C<Animal>c3 = new C();
C<String> c4 = newC();//会报错
三:泛型接口
1.使用
import java.util.ArrayList;
public interface Date<D> {
void add(D d);
ArrayList<D> getbyName(String name);
}
public class Student {
String name;
public Student() {
}
public Student(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
import java.util.ArrayList;
public class StudentDate implements Date<Student>{
@Override
public void add(Student student) {
}
@Override
public ArrayList<Student> getbyName(String name) {
return null;
}
}
public class DateTest {
public static void main(String[] args) {
Date<Student> s = new StudentDate();
s.add(new Student("王凯"));
s.add(new Student("蔡建宇"));
s.add(new Student("余洋"));
s.add(new Student("樊军鑫"));
s.getbyName("王凯");
}
}
实现泛型接口,分为两种情况:第一种情况:子类清楚的知道 泛型参数的类型;第二种情况:子类不知道是什么类型 。
//第一种情况
/*public class InterImpl implements Inter<String>{
@Override
public void show(String t) {
System.out.println(t);
}
}*/
//第二种情况
public class InterImpl<T> implements Inter<T>{
@Override
public void show(T t) {
System.out.println(t);
}
}
/*
* 泛型接口测试
*/
public class InterGenericTest {
public static void main(String[] args) {
//第一种情况测试
// Inter<String> i=new InterImpl();
// i.show("123");
//第二种情况测试
Inter<String> ii=new InterImpl<String>();
ii.show("java");
}
}
注意:泛型接口也可以继承其他类
四:泛型方法
1.泛型方法的使用:
import java.util.ArrayList;
public class TEST {
public static void main(String[] args) {
String rs = test("算了吧");
System.out.println(rs);
Dog d = test(new Dog());
ArrayList<Car> cars = new ArrayList<>();
cars.add(new Car());
cars.add(new Car());
go(cars);
ArrayList<BMW> bmws = new ArrayList<>();
bmws.add(new BMW());
bmws.add(new BMW());
go(bmws);
ArrayList<BENZ> benzs = new ArrayList<>();
benzs.add(new BENZ());
benzs.add(new BENZ());
go(benzs);
}
// public static <T> void go(ArrayList<T> cars){
//
// }不限定类型的用法
// public static <T extends Car> void go(ArrayList<T> cars){
//
// }限定类型的用法
public static void go(ArrayList<?> cars){
}//不限定类型的用法
// public static void go(ArrayList<? extends Car> cars){
//
// }限定类型的用法
public static <T> T test(T t){
return t;
}
}
2.通配符:就是"?",可以在"使用泛型"的时候代表一切类型;E T K V是在定义泛型的时候使用。
3.泛型的上下限:
泛型上限:? extends Car ?能接收的必须是Car或者其子类
泛型下限: ? super Car ?能接收的必须是Car或者其父类
五:泛型的擦除问题和注意事项
1.泛型是工作在编译阶段的,一旦编译成class文件,class文件中就不存在泛型了,这就是泛型擦除。
2.泛型不支持基本数据类型,只能支持对象类型(引用数据类型)。