`
windowboy
  • 浏览: 15255 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
社区版块
存档分类
最新评论

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;
      那么?类型只能是Number的子类,例如 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>()是非法的,将无法通过编译

  • 大小: 8.6 KB
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics