黑马程序员_JAVA-泛型

来源:互联网 发布:双色球矩阵计算器 编辑:程序博客网 时间:2024/05/16 01:57

------- android培训、java培训、期待与您交流! ----------


泛型是JDK1.5版本之后出现的新特性,用于解决安全问题
好处:
1.将运行时期出现问题ClassCastException,转移到了编译时期,方便程序员解决问题,让运行时期问题减少
2.避免了强制转换的麻烦
通过<>来定义要操作的数据类型

ArrayList<String> a1 = new ArrayList<String>();//限定集合成员类型为StringIterator<String> it = a1.iterator();class Utils<TR>//泛型类{     private TR q;     public TR getObject(){}}Utils<String>  u = new Utils<String>();


当类中操作的数据不确定时,早期定义Object来完成扩展,现在定义泛型来完成扩展。

泛型类定义的泛型,整个类中有效,如果被方法使用,那么
泛型类的对象明确要操作的具体类型后,所有要操作的类型就已经固定

为了让不同方法操作不同类型,而且类型还不确定,那么可以将泛型类定义在方法上。
public <Q> void show(Q q){}
泛型类中可以同时定义不同的泛型方法

class Demo<T>{     public void show(T t)     {          System.out.println("show:"+t);     }     public <Q> void print(Q q)     {          System.out.println("print:"+q);     }//静态方法不可以访问类上定义的泛型//如果静态方法操作的应用数据类型不确定,可以将泛型定义在方法上。     public static <W> void method(W w)     {          System.out.println("method:"+w);     }}//泛型定义在接口上interface Inter<T>{     void show(T t);}//如果实现仍不确定传入类型,可以继续用泛型定义class InterImpl<T> implements Inter<T>{     public void show(T t)     {          System.out.println("show:"+t);     }}//对象类型不确定时,可以用?public static void print(ArrayList<?> a1){     Iterator<?> it = al.iterator();     while(it.hasNext())     {          sop(it.next());     }}//也可以用Tpublic static <T> void print(ArrayList<T> a1){     Iterator<T> it = al.iterator();     while(it.hasNext())     {          sop(it.next());     }}//?通配符,也可以理解为占位符//不明确具体类型时用?表示//?可以定义用来接收具备多种泛型的数据public static void print(ArrayList<?> al){      Iterator<?> it = al.iterator();      while(it,hasNext())     {          System.out.println(it.next());     }}//"T"表示具体类型,可以接收数据public static <T> void print(ArrayList<T> al){      Iterator<T> it = al.iterator();      while(it,hasNext())     {          System.out.println(it.next());     }}


泛型限定
?  extends E:可以接收E类型或者E的子类型,上限
?  super  E:可以接收E类型或者E的父类型,下限

泛型是给javac编译器提供的类型限定
只要能跳过编译器就可以往某个泛型集合中加入其它类型的数据,例如,用反射得到集合在调用add方法。
collection.getClass().getMethod("add",Object.class).invoke(collection,"abc");

整个称为ArrayList<E>泛型类型
ArrayList<E>中的E称为类型变量或类型参数
整个ArrayList<Integer>称为参数化类型
ArrayList<Integer>中的Integer称为类型参数的实例化或实际类型参数
ArrayList<Integer>中的<>    typeof
ArrayList称为原始类型


创建数组实例时,数组元素不能使用参数化的类型

Vector v1 = new Vector<String>();
Vector<Object> v = v1;
编译不报错
Vector<Object> v = new Vector<String>();
编译报错
因为编译器是一行一行检查代码的


使用?通配符可以引用其他各种参数化类型,?通配符定义的变量主要用作引用,
可以调用与参数化无关的方法,不能调用与参数化有关的方法。

自定义泛型

只有引用类型(不是基本类型)才能作为泛型的基本参数,也可以用类型变量表示异常即参数化异常。
自己throw异常时可以抛T,catch时要明确所抛异常。

静态方法不能用类上的泛型限定。


通过反射获得泛型的实际参数类型

Method applyMethod = GenericTest.class.getMethod("applyVector.class");
Type[] types = applyMethod.getGenericTestParameterTypes();
ParameterizedType pType = (ParameterizedType)types[0];
pType.getRawType();//得到原始类型Vector
pType.getActualTypeArguments()[];//得到实际类型参数Data

public static void applyVector(Vector<Date> v1){}


0 0
原创粉丝点击