美文网首页
笔记:Java高级特性之泛型

笔记:Java高级特性之泛型

作者: 盐海里的鱼 | 来源:发表于2020-05-17 23:10 被阅读0次

    1.泛型是什么

    Java的泛型是一种伪泛型,只存在于编译期不存在于JVM运行期。它的JDK5引入的一种参数化类型。

    2.使用泛型的好处

    1. 将运行期可能出现的错误提前到编译期判断(只要编译期没有警告运行期就不会出现问题),提升代码的健壮性。
    2. 使代码更简洁(不需要进行类型强转)
        //不使用泛型
        RawPlate rawPlate = new RawPlate();
        rawPlate.set(new Apple());
        Banana bannana  = (Banana) rawPlate.get();
        //使用了泛型
        AiPlate<Banana> aiPlate = new AiPlate<>();
        aiPlate.set(new Apple());
        aiPlate.set(new Banana());
        Banana b = aiPlate.get();
      
    3. 提升代码的复用
         int[] ints = new int[10];
         sort(ints);
         double[] doubles = new double[10];
         sort(doubles);
         Object[] objects = new Object[10];
         sort(objects);
         
         public static void sort(int[] array){}
         public static void sort(double[] array){}
         public static <T> void sort(T[] array){}>
      

    3.泛型有哪几种:

    • 泛型类 :

      class Plate <T>
      class AiPlate<T> extends Plate<T>

    • 泛型接口

    interface Plate<T>

    • 泛型方法

      public <T> T getData(T t){return t; }

    4.泛型的继承原则:

    遵循类的单继承 接口的多继承原则,在继承关系中 类写在第一位,接口跟在后面 用&连接,只要继承原则中原始的T不变,类的继承关系就存在

      ```
       public class A< T extends ClassA & IB & IC & ID >{};
        class A<T>
        class B<T> extends A<T>
        class C<K,T> extends B<T>
     ```
    

    5.泛型的擦除原则:

    1.擦除时会擦除到第一层限制关系 如果没有则擦除成Object:

    如 Class <T extends Comparable<T>>
    2.生成桥方法是为了保持多态性

    1. Type类型会保留在常量池里
    补充数组协变:

    如 class Apple extends Fruilt那么 Apple[] 也会是 Fruit[]的子类

    6.泛型的限定符 、通配符<?>与PECS原则(Producer extends Consumer super)

    ```
      class A<T extends Fruit>  只能取 ,生产者 
      class B<T super Food>    只能放,消费者
      class C<?> 
     ```   
    
        public class Test1 {
      public static void main(String[] args) {
          //限定类型
          List<Apple> src  = new ArrayList<>(10);
          src.add(new Apple(1));
          List<Apple> dest  = new ArrayList<>(10);
          dest.add(new Apple(2));
          System.out.println(dest);
          copy(dest,src);
          System.out.println(dest);
    
          //更换泛型
          List<Banana> src2  = new ArrayList<>(10);
          src2.add(new Banana(1));
          List<Banana> dest2  = new ArrayList<>(10);
          dest2.add(new Banana(2));
          System.out.println(dest2);
          //调用copy 发现方法无法调用
          //copy(dest2,src2);
          copy2(dest2,src2);
          System.out.println(dest2);
    
          //使用父类型作为泛型
          List<Banana> src3  = new ArrayList<>(10);
          src3.add(new Banana(1));
          List<Fruit> dest3 = new ArrayList<>(10);
          dest2.add(new Banana());
        //  Test1.<Banana>copy2(dest3,src3);
          //这里 dest3的泛型是Fruit 泛型方法的泛型是Banana src的泛型是Banana copy3 dest3 ? super T 表述 fruit super banana
          Test1.<Banana>copy3(dest3,src3);
    
          List<Fruit> dest4 = new ArrayList<>(10);
          dest4.add(new Banana());
          //这里 dest4的泛型是Fruit 泛型方法的泛型是Banana src的泛型是Banana copy3
          // dest4 ? super T  表述 fruit super banana 
          // src3? extends T 表述为  Banana extends Fruit
          Test1.<Fruit>copy4(dest4,src3);
      }
    
      /**
       * 限定只能传入Apple
       * @param dest 目标 存入
       * @param src  源数据 取出
       * 从src取出一个apple  ->dest
       */
      public static void copy(List<Apple> dest,List<Apple> src){
          Collections.copy(dest,src);
      }
    
      /**
       * 限定同个T在调用时确定 但是都是同个类型
       * @param dest List<Fruit>
       * @param src List<Banana>
       * @param <T>
       * 从src取出一个apple  ->dest
       */
      public static <T> void copy2(List<T> dest,List<T> src){
          Collections.copy(dest,src);
      }
      /**
       * 限定上界
       * @param dest List<? super T> 限定存入 消费者的泛型 必须是 实际类型的父类
       * @param src  List<T> src 
       * @param <T>
       * 泛型是Fruit   banana ->fruit的子类
       */
      public static <T> void copy3(List<? super T> dest,List<T> src){
          Collections.copy(dest,src);
      }
    
    
      /**
       * 
       * @param dest List<? super T>  限定存入 消费者的泛型 必须是 实际类型的父类
       * @param src List<? extends T> 限定取出 生产者的泛型 必须是 实际类型的子类
       * @param <T> 实际方法的泛型
       */
      public static <T> void copy4(List<? super T> dest,List<? extends T> src){
          Collections.copy(dest,src);
      }
    }
    

    作业:

    说出一下类型的区别

    Plate:没有使用泛型的Plate类 class Plate{}
    Plate p = new Plate();
    Plate<Object>: 泛型为Object的Plate类
    class Plate<Object>{} Plate p = new Plate<Object>();
    Plate<?>: 通配的一个Plate类 class Plate<?>{}
    Plate p = new Plate<Apple>(), Plate p2 = new Plate<Object>();
    Plate<T>:泛型类型为T的类 class Plate<T>
    Plate p = new Plate<Apple>(),
    Plate<? extends T> 继承 T 的通配Plate 类 class Plate<? extends T>{} 假设 T为Fruit Apple Banana为Fruit的子类
    Plate p = new Plate<Apple>(), Plate p2 = new Plate<Banana>(),
    Plate<? super T> 父类为 T 的通配Plate 类 class <? super T>{} 假设T为Food Fruit为Food的子类 Apple Banana为Fruit的子类
    Plate p = new Plate<Apple>(), Plate p2 = new Plate<Banana>(),

    相关文章

      网友评论

          本文标题:笔记:Java高级特性之泛型

          本文链接:https://www.haomeiwen.com/subject/qqysohtx.html