美文网首页
笔记: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高级语言特性之泛型

    Java高级语言特性之泛型 Java泛型(generics)是JDK 5中引入的一个新特性,泛型提供了编译时类型安...

  • 笔记:Java高级特性之泛型

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

  • Kotlin泛型的高级特性(六)

    泛型的高级特性1、泛型实化2、泛型协变3、泛型逆变 泛型实化 在Java中(JDK1.5之后),泛型功能是通过泛型...

  • Java高级特性之泛型

    前言 想写一下关于 Java 一些高级特性的文章,虽然这些特性在平常实现普通业务时不必使用,但如果想写出优雅而高扩...

  • java 高级特性之泛型

    一. Java 中的泛型 Java 5 中添加了泛型,用以编译时类型检查,借此消除使用集合类时常见的ClassCa...

  • Kotlin-泛型和委托

    泛型 泛型的使用是为了程序有更好的扩展性。泛型类和泛型方法 泛型的高级特性java的泛型是通过类型擦除机制来实现的...

  • Java高级特性-泛型:泛型的基本用法,怎样才能少写 1 万行代

    泛型是 Java 的一个高级特性。在 Mybatis、Hibernate 这种持久化框架,泛型更是无处不在。 然而...

  • Java 高级特性——泛型

    声明这是我上课学到的, 为什么我们需要泛型? 通过两段代码我们就可以知道为何我们需要泛型 实际开发中,经常有数值类...

  • 通配符的上下限与泛型方法

    java零基础入门-高级特性篇(七) 泛型 下 本章阅读有难度,请谨慎阅读,如有不适,可以跳过。 本章继续讲解泛型...

  • JAVA-泛型

    JAVA-泛型 sschrodinger 2018/11/15 简介 泛型是Java SE 1.5的新特性,泛型的...

网友评论

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

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