1. 泛型
(1) 泛型:定义类、接口、方法时,同事声明了一个或多个类型变量(如<E>),称为泛型类、泛型接口、泛型方法、它们统称为泛型。可以在编译阶段约束要操作的数据类型
public static void main(String[] args) {//没加泛型 可以放任何类型的数据ArrayList list = new ArrayList();list.add("卡莎");list.add(123);list.add('c');for (int i = 0; i < list.size(); i++) {System.out.println(list.get(i));}//加泛型 只能放String类型ArrayList<String> list1 = new ArrayList<>();//从JDK1.7开始,后面的泛型<>可以不声明list1.add("卡莎");list1.add("艾卡西亚");//list1.add(123);for (int i = 0; i < list1.size(); i++) {String str = list1.get(i);System.out.println(str);}
}
(2) 作用:泛型提供了在编译阶段约束所能操作的数据类型,并自动进行检查的能力,这样可以避免强制类型转换及其可能出现的异常。
(3) 泛型的本质就是把具体的数据类型作为参数传递给类型变量
2. 泛型类
(1) 格式:修饰符 class 类名<类型变量, 类型变量,.....>{ ..........}
类型变量建议使用大写的英文字母,常用的有E、T、K、V等
//泛型类
public class MyArray<E> {Object[] array = new Object[10];private int size = 0;//记录当前位置public boolean add(E e) {array[size++] = e;return true;}public E get(int index) {return (E)array[index];}
}//多个泛型 类
public class MyArray2<E,D> {public void put(E e, D d) {}
}//动物类
public class Animal {}//狗继承动物类
public class Dog extends Animal{}//继承泛型类
public class MyArray3<E extends Animal> {}//测试public static void main(String[] args) {//泛型类//单个泛型限定StringMyArray<String> array = new MyArray();array.add("卡莎");array.add("艾卡西亚");String a = array.get(0);//卡莎System.out.println(a);//多个泛型限定 String,StringMyArray2<String,String> array2 = new MyArray2<>();array2.put("卡莎","艾卡西亚");array2.put("泰坦","勾");//泛型限定必须为Animal的继承者 Dog继承AnimalMyArray3<Dog> array3 = new MyArray3<>();}
3. 泛型接口
(1) 格式:修饰符 interface 接口名<类型变量,类型变量,......> { ......}
类型变量建议使用大写的英文字母,常用的有E、T、K、V等
泛型接口中泛型也可为<E extends Animal> 此时的泛型必须为Animal的继承者
//泛型接口
public interface Data<E> {void add(E e);ArrayList<E> get(String name);
}//泛型继承接口
public interface Data1<E extends Animal> {void add(E e);ArrayList<E> get(String name);
}//老师实体类
public class Teacher {}//学生实体类
public class Student {}//老师实现Data接口 泛型为老师实体类
public class TeacherData implements Data<Teacher>{@Overridepublic void add(Teacher teacher) {}@Overridepublic ArrayList<Teacher> get(String name) {return null;}
}//学生实现Data接口 泛型为学生实体类
public class StudentData implements Data<Student>{@Overridepublic void add(Student student) {}@Overridepublic ArrayList<Student> get(String name) {return null;}
}
4. 泛型方法、泛型通配符、上下限
(1) 泛型方法格式: 修饰符<类型变量,类型变量,.....> 返回值类型 方法名(形参列表){...}
(2) 通配符
就是 ?,可以在"使用泛型"的时候代表一切类型;E T K V是在定义泛型的时候使用
(3) 泛型的上下限
泛型上限: ? extends Animal : ?能接收的必须是Animal或者他的子类
泛型下限:? super Animal:?能接收的必须是Animal或者他的父类
public class Test3 {public static void main(String[] args) {//泛型方法String s = show("java");Integer i = show(123);char c = show('c');Boolean falg = show(false);Dog dog = show(new Dog());}//泛型方法public static <T> T show(T t){return t;}//泛型继承方法public static <T extends Animal> T show(T t){return t;}// ? 通配符 在使用泛型的时候可以代表一切类型public static void run(ArrayList<?> list){}// ? 通配符继承 在使用泛型的时候可以代表一切类型 Animal(上限)的子类public static void run1(ArrayList<? extends Animal> list){}//super Animal(下限) Animal的父类public static void run3(ArrayList<? super Animal> list){}
}
5. 泛型擦除问题、基本数据类型问题
(1)泛型是工作在编译阶段的,一旦程序编译成class文件,class文件中就不存在泛型了,这就是泛型擦除
(2)泛型不支持基本数据类型,只能支持对象类型(引用数据类型),可以使用基本数据类型的包装类
public static void main(String[] args) {//泛型擦除问题、基本数据类型问题//1.泛型是工作在编译阶段的,一旦程序编译成class文件,class文件中就不存在泛型了,这就是泛型擦除ArrayList<Integer> list = new ArrayList<Integer>();list.add(1);list.add(2);list.add(3);Integer i = list.get(0);System.out.println(i);//2.泛型不支持基本数据类型,只能支持对象类型(引用数据类型)//ArrayList<int> list2 = new ArrayList<int>();}
编译之后的问文件:
基本数据类型的包装类:
基本类型 | 包装类(引用类型,包装类都位于java.Lang包下) |
byte | Byte |
short | Short |
int | Integer 【特殊】 |
long | Long |
float | Float |
double | Double |
char | Character 【特殊】 |
boolean | Boolean |