黑马程序员_JAVA-泛型

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


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

ArrayList<String> a1 = new ArrayList<String>();
//限定集合成员类型为String
Iterator<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());
     }
}
//也可以用T
public 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
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值