我觉得首先要明白什么是泛型?泛型的作用?最后才是泛型怎么用?
1,什么是泛型?
泛型就是在声明类或接口的时候,通过一个标示表示类中某个成员变量的类型、类中方法的返回这类型和参数类型,泛型是表示类或方法对未知类型的一种约束。泛型就是具有一个或者多个类型变量的类。
2,泛型的作用
泛型主要是解决数据类型的安全问题。
3 声明泛型类
//声明一个泛型类,在实例化Number时,指明T的类型
public class Number<T>{
//声明一个泛型类型变量
T t;
}
public class Test{
public static void main(String[] args){
Number<Integer> num = new Number<Integer>();
}
}
声明泛型方法
泛型方法和泛型类没有关系,就是说不是泛型类同样可以有泛型方法
public class Number {
public static <K> void setTT(K t) {
}
public <T> void getT(T t) {
}
//如果说是泛型类Number<T>,标示是T,在方法中返回值或者是方法参数也是T类型,编译器建议省略<T>.如下
public void getT(T t) { }
// 如果在方法中泛型标示在类中没有,必须在方法中表明<T>
// static方法无法获取类中的泛型参数列表,必须在方法中声明泛型参数列表
}
泛型通配符
Person<?> p1 = new Person<>();
Person p2 = new Person();
存取原则
通配符上线
public void setList(List<? extends Person> list) {
list.add(null);// 上线只能添加null元素
// 因为List<? extends Person> 是List<Person>和 List<Person子类>的父类
// 如果list 是List<Person子类1>,那么List<Person子类 234..>就不能添加进去,为了保证
// 类型的安全性,编译期就不能通过,null 是所有类型的子类,是可以添加的,也只能添加null一个元素
// 所以通配符上线能读 不能添加
}
public void getList(List<? super Person> list) {
List<? super Person> list1 = new ArrayList<Person>();
list1.add(new SubPerson());
list1.add(new Stu());//编译错误
// 因为List<? super Person> 肯定是Person 的父类,所以添加Person 和Person
//的子类是没有问题的,假设说Person1 继承Person2,Person2继承Person3
//如果list是<Person2>,是可以添加person1的,但是添加person3 就是错误的。
Object object = list.get(0);//读取默认是Object 类型,因为不知道是什么类型的
//所以通配符下线是可以添加元素,但是不能读取元素。
注意;如果说A 集成B A extends B
List<A>不是List<B>的子类
list<A>是List<? extends B>的子类。
泛型的擦除
在java字节码中是不存在泛型的概念的,泛型发生在编译期,并在编译前检查错误,java 类在编译后,都会变成原始类型
ArrayList<Integer> arrayList3=new ArrayList<Integer>();
arrayList3.add(1);//这样调用add方法只能存储整形,因为泛型类型的实例为Integer
arrayList3.getClass().getMethod("add", Object.class).invoke(arrayList3, "asd");
for (int i=0;i<arrayList3.size();i++) {
System.out.println(arrayList3.get(i));
}
//Integer泛型实例在编译之后被擦除了,只保留了原始类型