泛型:jdk1.5之后出现的新特性,用于解决安全问题,是一个安全机制

好处:1 将运行时期的问题转移到编译时期,方便程序员解决问题
      2 避免的强制转换的麻烦
      3 提高了编译时期的安全性。

<>:什么时用?当操作的引用数据类型不确定的时候,就用<>将要操作的引用数据类型传入

<>就是一个用于接收具体引用数据类型的参数范围。


在程序中,只要用到了带有<>的类或者接口,就要明确传入的具体引用数据类型。
class Tool<e1,e2,e3,e4>//<>中可以接收多个类型参数;
Tool<String,Demo,Person,Man> t = new Tool<String,Demo,Person,Man>();


注释:泛型技术是给编译器使用的技术,用于编译时期。确保了类型的安全。

运行时,会将泛型去掉,生成的class文件中时不带泛型的,这个称之为泛型的擦除。
为什么擦除呢?为了去兼容运行时的类加载器(1.4,1.5同一个类加载器)。

泛型的补偿:在运行时通过获取元素的类型进行转换动作,不用使用者再强制转换了。
-------------------------------
泛型在集合中的应用

--------------------------------
泛型在设计时好处
  当函数的具体实现不知道是使用抽象函数,
  当操作的对象类型不确定时使用泛型。
1 泛型类
  当类中操作的引用数据类型不确定的时候就采用泛型。

calss Tool<T>
    {
       private T t;
       public void get()
       {
          return t;
        }
       public void set(T t)
       {
          this.t = t;
       }
      }
      
      Tool<Person> tool = new Too<Person>();//指定tool操作的对象为Person
                                            // 提高安全性 
      tool.set(new Person());
      Worker w = tool.get();//会报异常   (在使用泛型前异常发生在运行时期
                                           现在异常会出现在编译时期)



2  泛型方法
   

public<T>viod show(T str)
   {
     
       System .out.println(str);
     
   }




   静态方法:不能访问类上定义的泛型。
   只能讲泛型定义在方法上

public static <Y> void method(Y obj)
    {
       System.out.println(obj);
    }



3  泛型接口
   

interface Inter <T>
    {
        public void show(T t);//不明确show参数的具体类型--> 泛型?为啥不定义在方法上?而是定义在类上?
     }                                                      答:即可定义在方法上,也可定义在类上
                                                                只是作用域不同,定义在类上对整个类可见
                                                                定义在方法上:对该方法可见。


    //接口实现类
    class InterImp implements Inter<String>//当实现类知道该接口的方法操作的数据类型时
 {
     pulic void show(String t)
     {
        System.out.println(t)
     }
 }

   class InterImp<Q> implements Inter<Q>//当实现类不知道该接口的方法操作的数据类型时:可继续在实现类上定义泛型
 {
     pulic void show(Q q)
     {
        System.out.println(q)
     }
 }

       InterImp<String> inter = new InterImp<String>();//在具体使用时才传参给泛型
       inter.show("dasda");





    interface Inter//当泛型定义在接口方法上时:
 {
     public<T> void show(T t);
 }

 class InterImp implements Inter
 {

     @Override
     public <T> void show(T t) {
         // TODO Auto-generated method stub
         System.out.println(t);
     }
     
 }

javautil工具类 java中工具类的作用_泛型



--------------------------
泛型的限定

public static void printCollection(/*Collection<String>*/Collection<?> c)//当不确定集合中所装元素类型,
                                                                           //但有不调用元素类型具体方法时:可使用泛型通配符 ?
   {
         //Iterator<String> it = c.iterator();
           Iterator<?> it = c.iterator();
         while(it.hasNext())
          {
             //String str = it.next();
               ? str = it.next();
           }
    }

     
    public static <T> void printCollection(Collection<T> c)//当方法上定义泛型T:是希望通过T代表的
                                                           //的具体某一类型,对元素进行一些操作。
   {
         Iterator<T> it = c.iterator();
         while(it.hasNext())
          {
             T str = it.next();
              
           }
    }




  限制上限:
   
   ? extends E:接收E或E的子类型

public static void printCollection(Collection<? extends Person> c)//需求:集合中装入的是一个体系的对象才能打印。
   {
         Iterator<? extends Person> it = c.iterator();
         while(it.hasNext())
          {
            Person p = it.next();
            System.out.println(p.getName());//因为存储的都是person的子类所有都具备person的方法
              
           }
    }



  限制下限:
  ? super E:接收E或 E的父类型。下限
   

public static void printCollection(Collection<? super Student> c)//
   {
         Iterator<? super Student> it = c.iterator();
         while(it.hasNext())
          {
            //Person p = it.next();
            //System.out.println(p.getName());
              System.out.println(it.next());
              
           }
    }


--------------------------------
 上限的体现
 通常对结合中的元素进行取出操作时:可以使用下限
   
 Collection中的
 
 addAll(Collection<? extends E> c);:E时创建Collection时传入的

// Collection<E> c = new Collection<E>;
    Collection<Person> c = new Collection<Person>;: 此时E == Person


 
   往集合中存元素时:通常定义上限。
   因为这样取出时:都是按照上限类型来运算了,这样不会出现类型安全隐患。


  下限的体现
   

TreeSet (Comparator<? super E> comparator);

    class TreeSet<E>
    {
       TreeSet (Comparator<? super E> comparator);
    }


   当TreeSet中装的是学生时?要定义学生的比较器。
   当TreeSet中装的是工人时?要定义工人的比较器。 这两个比较器的实现方式是相同的都是按照Person比较器内容实现的
 

class TreeSet<Student>
    {
       TreeSet (Comparator<Student> comparator);
    }
     
      class TreeSet<Worker>
    {
       TreeSet (Comparator<Worker> comparator);
    }
    
    class TreeSet<Student>
    {
       TreeSet (Comparator<? super Student> comparator);
    }
     
      class TreeSet<Worker>
    {
       TreeSet (Comparator<? super Worker> comparator);
    }



   要进行比较:得把集合中的元素取出来,所以可以用父类来接收子类的对象

  定义比较器时:

class compByname implements Comparator<Person>
   {

   }