泛型复习
回顾泛型类
泛型类:具有一个或多个泛型变量的类被称之为泛型类
1、class A<T>{
}
2、在创建泛型实例时,需要为其类型变量赋值
A<String> a=new A<String>();
*如果创建实例时,不给类型变量赋值,那么会有一个警告!
3、泛型方法:具有一个或多个类型变量的方法,称之为泛型方法!
class A<T>{
public T fun(T t1){}
}
fun()方法不是泛型方法!它是泛型类中的一个方法!
public <T> T fun(T t1){} -->它是泛型方法
*泛型方法和泛型类没有什么关系,泛型方法不一定非要在泛型类中!
4、泛型在类中或者方法中的使用
*泛型类中使用泛型:
>成员类型
>返回值类型和参数类型
>局部变量的引用上
class A<T>{
private T bean;//泛型可在成员变量上使用
public T fun(T t){}//泛型可以在类中的方法上(返回值和参数类型)使用!
public void fun2(){//泛型还可以在局部变量的引用类型上使用
T b=...
new T();//不行的
}
}
=====================================
5、泛型的继承和实现
class A<T>{}
class AA extends A<String>{} //不是泛型类,只是它爸爸是泛型类!
5.1 继承泛型类
*子类不是泛型类:需要给父类传递类型常量
>当给父类性传递的类型常量为String时,那么在父类中所有T都会被String替换
*子类是泛型类:可以给父类传递类型常量,也可以传递泛型变量
class AA1 extends A<Integer>{}
class AA3<E1> extends A<E1>(){}
============================================
泛型的通配符
1、通配符的使用场景
方法的形参!
2、通配符的优点
使方法更加通用!
3、通配符分类
无界通配 ?
子类限定:? extends Object
父类限定:? super Integer
4、通配符缺点
使变量使用上不再方便
无界:参数和返回值为泛型的方法不能使用
子类:参数为泛型的方法不能使用
父类:返回值为泛型的方法不能使用
5、比较通配符
boolean addAll(Collection<E> c)
List<Number> numList=new ArrayList<Number>();
List<Integer> intList=new ArrayList<Integer>();
numList.add(intList);//编译失败
boolean addAll(Collection<? extends E> c)
List<Number> numList=new ArrayList<Number>();
List<Integer> intList=new ArrayList<Integer>();
numList.add(intList);
package cn.itcast; import org.junit.Test; public class Demo1 { @Test public void fun1(){ AA3<Long> aa3=new AA3<Long>(); } } class A<T>{ private T t; public T fun1(){ return t; } public void fun2(T t){ this.t=t; } } class AA1 extends A<Integer>{ } class AA2 extends A<String>{ } class AA3<E> extends A<E>(){ } package cn.itcast; import java.util.ArrayList; import java.util.List; import org.junit.Test; public class Demo2 { @Test public void fun1(){ Object[] objs=new Object[10]; List list=new ArrayList(); String[] strs=new String[10]; List<String> strList=new ArrayList<String>(); Object[] objArray=new String[10]; objArray[0]=new Integer(100);//java.lang.ArrayStoreException: java.lang.Integer // List<Object> objList=new ArrayList<String>(); /* * 泛型引用和创建两端,给出的泛型变量必须相同! */ } public void fun2(){ List<Integer> integerList=new ArrayList<Integer>(); print(integerList);//List<Object> list=new ArrayList<Integer>(); List<String> strList=new ArrayList<String>(); print(strList); } /* * 这个?就是通配符 * 通配符只能出现在左边!,即不能再new时使用通配符!!! * List<? extends Object> list=new ArrayList<String>(); */ /* * ?它表示一个不确定的类型,它的值会在调用时调用下来 */ public void print(List<?> list){ /* * 当使用通配符,对泛型类中参数为泛型的方法起到了副作用 */ //list.add("hello"); /* * 当使用通配符时,泛型类中返回值为泛型的方法也作废了 */ Object s=list.get(0); /* * 通配符的好处:可以使泛型类型更加通用!尤其是在方法调用时形参使用通配符 */ } public void fun3(){ List<Integer> intList=new ArrayList<Integer>(); print1(intList); List<Long> lonList=new ArrayList<Long>(); print1(lonList); // List<String> strList=new ArrayList<String>(); // print1(strList); } /* * 给通配符添加了限定 * 只能传递Number或其子类 * 子类统配对通用性产生了影响,但使用形参更加灵活 */ public void print1(List<? extends Number> list){ /* * 参数为泛型的方法还是不能使用 */ // list.add(new Integer(100)); /* * 返回值为泛型的方法可用 */ Number number=list.get(0); } public void fun4(){ List<Integer> intList=new ArrayList<Integer>(); print2(intList); // List<Long> lonList=new ArrayList<Long>(); // print2(lonList); List<Object> objList=new ArrayList<Object>(); print2(objList); } /* * 给通配符添加了限定 * 只能传递Integer类型,或其父类型 */ public void print2(List<? super Integer> list){ /* * 参数为泛型的方法可以使用了 */ list.add(new Integer(100)); // Integer int1=list.get(0); /* * 返回值为泛型的方法,还是不能使用 */ Object obj=list.get(0); } }
反射获取类上面的泛型信息:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
package cn.itcast.demo1; import java.lang.reflect.ParameterizedType; import org.junit.Test; public class Demo1 { @Test public void fun1(){ new C(); } } class A<T>{ public A(){ /* * 在这里获取子类传递的泛型信息 */ // Type type=this.getClass().getGenericSuperclass();//获取父类的参数化类型 格式为A<String>或。。。 // ParameterizedType pType=(ParameterizedType) type; // Class c=(Class) pType.getActualTypeArguments()[0];//参数的Class数组 Class c=(Class)((ParameterizedType)this.getClass().getGenericSuperclass()).getActualTypeArguments()[0]; System.out.println(c.getName()); } } class B extends A<Integer>{ } class C extends A<String>{ }