java基础之泛型

讲解泛型之前,先看看如下的例子

    List list = new ArrayList();
    list.add(999);
    list.add("abc"); 
    list.add(new Date());
那么对于的数据是怎么加载进去的呢,jdk源码是这样的


 
list.add都是默认增加Object类型数据,但是在数据获取中就必须要知道每个数据的类型,而且很容易产生 ClassCastException异常,那么在jdk1.5引入泛型的概念.
指定list中存储的参数类型,如: List<String> list = new ArrayList<String>();这样就指定list只能装载String类型的数据。
但是在编译的时候出现一个奇怪的现象:
java代码
  List <String>  list = new ArrayList <String> ();
    list.add("999");
    list.add("abc");
编译后的代码
<String>参数消失了
1. 泛型原理类型擦出( type erasure
类型擦除的关键在于从泛型类型中清除类型参数的相关信息,并且再必要的时候添加类型检查和类型转换的方法在使用泛型时,任何具体的类型都被擦除,唯一知道的是你在使用一个对象。比如:List<String>List<Integer>在运行事实上是相同的类型。他们都被擦除成他们的原生类型,即List
在此有一个问题,既然泛型类型中清除了相关参数,那么系统又是如何在数据返回的时候自动转换呢?
通过两个步骤来解决
1.编译期会自动对传递进来的值进行检测,例如:List<String> list 对于增加list.add(9999)的时候编译会报错。
2.获取数据会把 获取的值按照传递的参数类型转换,list.get(0)的时候,系统会自动对这些值进行String的转换。
父类和子类在泛型中注意事项
       List<String> childrenList = new ArrayList<String>();
       List<Object> parentList = new ArrayList<Object>();
       一下两种形式都不能转换
      hildrenList = parentList;
      parentList =  childrenList;
      在泛型一个 List 中装入了各种不同类型的对象类型,这显然是不可以的,
      因为我们在取出 List 中的对象类型时, 就分不清楚到底该转型为哪种具体类型了(获取数据泛型会自动对传递的类型按参数设定的转换
泛型定义注意
 public  static  <T> List<T> get(String tu){
           return null;   
 }
 public    <T> List<T> getBO (String tu){
           return null;    
 }
2. 通配符:这里使用了通配符?指定可以使用任何类型的集合作为参数
注意:试图往使用通配符?的集合中加入对象,就会在编译时出现错误。  这是因为通配符?表示该集合存储的元素类型未知,可以是任何类型;因为该集合存储的元素类型未知,所以不能向集合中添加任何元素。
     List<?> list = someMothod(arg);
     list.add(object);//编译的时候会报错。
但是 List<?> list中获取对象,虽然不知道List中存储的是什么类型,但是可以肯定的是存储的类型一定是Object的子类型,所以可以用Object类型来获取值。如for(Object obj: list)循坏获取对象,这个事允许的。
2.1   ?extends通配符    
        类型  children extends parent  通配符必须是父类的子类。也称作限定通配符。
      List<? extends Number> list;
      那么?类型只能是N umber的子类,例如 Integer,Long,Float等,但是这里不能list.add(String)。
     在获取数据的时候
      取出其中对象时,可以使用 Number 类型来取值,因为虽然我们不知道列表中的元素类型具体是什么类型,
       但是一定是 Number 类的子类型。
            for(Number m:list){
                   .....
            }
2.2 ?super通配符
类型  A    super B     通配符A必须是B类的超类
      List<? super B> list;

  这表示list存储的元素为B的超类,因此可以往其中加入B对象或者B的子类对象,但是不能加入其他对象,只要是B或者B的子类,则一定是与该元素类别兼容。

    具体使用规则:   一个数据类型里获取数据,使用 ? extends 通配符

                               把对象写入一个数据结构里,使用 ? super 通配符

3.泛型方法:泛型方法的格式,类型参数<T>需要放在函数返回值之前。然后在参数和返回值中就可以使用泛型参数
    public  static  <T> List<T> get(String tu){
            return null;    
     }
     public <T> List<T> getBO (String tu){
              return null;      
      }
      public <T> void getM1(T obj){
       }
另外实际中经常出现的汇总一下;
1》.   
泛型类型是被所有调用共享的

       所有泛型类的实例都共享同一个运行时类,类型参数信息会在编译时被擦除。

          List<String> list1 = new ArrayList<String>();  

         List<Integer> list2 = new ArrayList<Integer>();  

         System.out.println(list1.getClass() == list2.getClass()); //True 

2》 数组是协变的,如:Object[] objArray = new Long[10]是合法的,因为Long是Object的子类,与之相反,泛型是不可协变的,如List<Object> objList = new List<Long>()是非法的,将无法通过编译

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值