泛型是JDK5中新引入的特性,可以在编译阶段约束操作的数据类型,并进行检查;泛型只支持引用数据类型;
一、泛型
泛型的格式:<数据类型>
1.好处
统一数据类型;把运行期间的问题提前到了编译期间,避免了强制转换类型可能出现的异常;因为在编译阶段类型都能确定下来
2.注意
泛型中不能写基本数据类型(写其包装类);
指定泛型的具体类型后,传递数据时,可以传入该类类型或者其他子类型;
如果不写泛型,类默认是object
3.泛型类
如果在一个类中,某个变量的数据类型不确定,就可以定义带有泛型的类
格式: 修饰符 class 类名 <类型>{}
eg: public class ArrayList <E>{}创建该类的对象时,E就会确定类型;E是用来记录数据类型的
import java.util.Arrays;
public class MyAarryList<E>{
Object[] obj = new Object[10];
int size;
/*E 表示不确定的类型
e 形参的变量名
*/
public boolean add(E e){
obj[size] = e;
size++;
return true;
}
/*obj[size] = e;:将传入的元素存储在数组中当前size所指的位置。
size++;:增加size的值,表示列表中的元素个数增加了一个。
返回值为true,表示添加成功。*/
public E get(int index){
return (E)obj[index];
}
@Override
public String toString() {
return Arrays.toString(obj);
}
}
public class MyAarryListtest {
public static void main(String[] args) {
MyAarryList <String> list = new MyAarryList<>();
//创建对象时将String传递给了E
list.add("aaa");
list.add("bbbb");
System.out.println(list);
MyAarryList <Integer> list1 = new MyAarryList<>();
//创建对象时将String传递给了E
list1.add(123);
list1.add(234);
int i = list1.get(0);
System.out.println(i);
System.out.println(list1);
}
}
4.泛型方法
当方法中形参类型不确定时,a.使用类名后面定义的泛型(所有方法都能使用) b.在方法声明上定义自己的泛型(只有本方法能够使用)
格式:修饰符 <类型> 返回值类型 方法名(类型 变量名){} eg:public <T> void show(T t){}
此方法可以理解为变量,但是不是用来记录数据的,而是用来记录类型的
import java.util.ArrayList;
public class ListUtil {
private ListUtil(){}
//定义一个静态方法 用来添加多个集合的元素
public static <E> void addAll(ArrayList<E> list,E e1,E e2,E e3){
list.add(e1);
list.add(e2);
list.add(e3);
}
}
import java.util.ArrayList;
public class ListUtiltes {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
ListUtil.addAll(list,"aaa","bbb","ccc");
System.out.println(list);
}
}
5.泛型接口
格式: 修饰符 interface 接口名<类型> {}
使用: a.实现接口的类给出具体的类型
b.实现类延续泛型,创建实现类对象时再确定类型
5.泛型的继承和通配符
泛型不具备继承性(泛型里面写的什么数据类型,那么只能传递什么数据类型),但是数据具备继承性
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;
public class MyArrayList2 {
public static void main(String[] args) {
ArrayList<ye> list1= new ArrayList<>();
ArrayList<fu> list2= new ArrayList<>();
ArrayList<zi> list3= new ArrayList<>();
method(list1);
//method(list2);//报错 不具有继承性
//list1.add(new fu());//不报错 数据具有继承性
method1(list2);
method1(list1);
method1(list3);
method2(list1);
method2(list2);
method2(list3);//报错
}
/*
?表示不确定的类型 也可以进行类型的限定
? extends E表示可以传递E 或者E的所有的子类类型
? super E表示可以传递E或者E的所有的数据类型
*/
// public static void method(ArrayList<ye> list){
//
// }
public static void method(ArrayList<?> list){
//? 所有的类型都可以传递过来 前面不用定义
/*
public static <E> void method(ArrayList<E> list){}
*/
}
public static void method1(ArrayList<? extends ye> list){}
public static void method2(ArrayList<? super fu> list){
}
}
class ye{}
class fu extends ye {}
class zi extends fu {}
应用场景:在定义类方法和接口的时候,如果类型不确定,就可以定义泛型类、泛型方法、泛型接口 ; 如果类型不确定,但是能知道以后只传递某个继承体系中的,就可以使用泛型的通配符