zoukankan      html  css  js  c++  java
  • java核心卷轴之泛型程序设计

      本文根据《Java核心卷轴》第十二章总结而来,更加详细的内容请查看《Java核心卷轴》

    1. 泛型类型只能是引用类型,不可以使用基本数据类型。

    2. 类型变量含义

       E : 集合    K : 关键字    V :       T : 任意类型

    3. 泛型类

      3.1  注意事项

        类型变量声明放在类名的后面

      3.2 示例

    package com.BlueStarWei.generic;
    
    public class Pair<T> {
        
        private T first;
        private T second;
        
        public Pair(T first, T second) {
          this.first = first;
          this.second = second;
        }
        
        public T getFirst() {
          return first;
        }
        public void setFirst(T first) {
          this.first = first;
        }
        public T getSecond() {
          return second;
        }
        public void setSecond(T second) {
          this.second = second;
        } 
    }

    4. 泛型方法

      4.1 注意事项

        类型变量放在修饰符的后面,返回类型的前面

      4.2 示例

    package com.BlueStarWei.generic;
    
    public class GenericMethodDemo{
       public static void main(String[] args) {
         String s = getMiddle("Hello","world","Happy");
         System.out.println(s);//World
       }
       
       //T... 表示可以输入任意个数的参数
       public static <T> T getMiddle(T... a){
         return a[a.length / 2];
       }
    }

    5. 类型变量的限定<T extends BoundingType>

      5.1 T应该是绑定类型的子类型。T和绑定类型可以是类,也可以是接口。

      5.2 一个类型变量可以有多个限定;如: T extends Comparable &  Serializable

      5.3 示例

    package com.BlueStarWei.generic;
    
    public class BoundingTypeDemo {
       public static void main(String[] args) {
         Integer[] a = new Integer[]{1,2,3,4};
         int max = getMax(a);
         System.out.println(max);
        
       }
       
       public static <T extends Comparable<T>> T getMax(T[] a){
         if(a == null || a.length == 0) return null;
         T max = a[0];
         for (int i = 0; i < a.length; i++) {
          if(max.compareTo(a[i]) < 0){
            max = a[i];
          }
        }
         return max;
       }
       
    }

    6. 运行时类型检查只适用于原始类型

      6.1 校验情况

    if(a instanceof Pair<String>) //编译报错
    if(a instanceof Pair<T>) //编译报错
    if(a instanceof Pair) //true

      6.2 getClass返回的是原始类型

    Pair<String> a = new Pair<String>("Hello", "World");
    Pair<Integer> b = new Pair<Integer>(1,2);
    if(a.getClass().equals(b.getClass())){
      System.out.println("true");
      //class  com.ebao.gs.pol.nb.test.Pair
      System.out.println(a.getClass());
    }else{
      System.out.println("false");
    }

    7. Java不支持泛型类型的数组

      7.1 示例

    Pair<String>[] as = new Pair<String>[10]; //编译报错

      7.2 解决方案: 将参数化对象放入ArrayList

    List<Pair<String>> list = new ArrayList<Pair<String>>();

    8. 通配符的限定

      8.1 子类型限定

        8.1.1 Pair<? Extends Employee>不能调用setFirst方法,但是可以调用getFirst方法

    extends Employee  getFirst()
    void setFirst(? extends Employee)

       调用setFirst方法时,编译器只知道需要某个Employee的子类型,但是不知道具体什么类型。它拒绝传递任何特定类型(?不能用来匹配)。调用getFirst方法时,只是将getFirst的返回值赋值给一个Employee的引用,完全合法。

        8.1.2 示例

    public static void minMaxBonus(Manager[] manager, Pair<?     
      extends Manager> result) {
    if(manager.length == 0 || manager == null) return;     
    Manager minManager = manager[0];
    Manager maxManager = manager[0];
    for (int i = 0; i < manager.length; i++) {
           if(manager[i].getBonus() < minManager.getBonus())   
                minManager = manager[i];
           if(manager[i].getBonus() > maxManager.getBonus()) 
                maxManager = manager[i];
    }
    result.setFirst(minManager);//编译报错
    result.setSecond(maxManager);//编译报错
    Manager m = (Manager)result.getFirst();
    System.out.println(m.getBonus());

      8.2 超类型限定

        8.2.1 Pair<? super Manager>可以调用setFirst方法,但是调用getFirst方法会返回Object对象(可以类型强转)

    void setFirst(? super Manager)
    ? super Manager getFirst()

      编译器不知道setFirst方法的确切类型,但是可以用任意Manager对象(或子类型)调用它。然而,如果调用getFirst方法,返回的对象类型就得不到保证。只能把它赋值给一个Object(但是可以类型强制转换)。

        8.2.2 示例

    public static void minMaxBonus(Manager[] manager, Pair<? 
      super Manager> result) {
      if(manager.length == 0 || manager == null) return;
      Manager minManager = manager[0];
      Manager maxManager = manager[0];
          for (int i = 0; i < manager.length; i++) {
            if(manager[i].getBonus() < minManager.getBonus()) 
                 minManager = manager[i];
            if(manager[i].getBonus() > maxManager.getBonus()) 
                 maxManager = manager[i];
        }
      result.setFirst(minManager);
      result.setSecond(maxManager);
      Manager m = (Manager)result.getFirst();
      System.out.println(m.getBonus());
            
    }

      8.3 总结

        通常而言:带有超类型限定的通配符可以向泛型对象中写入,带有子类型限定的通配符可以从泛型对象中读取。

      8.4 附表(Manager类)

    package com.ebao.gs.pol.nb.test;
    
    public class Manager {
      private Long id;
      private String name;
      private Double bonus;
      
      
      public Manager(Long id, String name, Double bonus){
        super();
        this.id = id;
        this.name = name;
        this.bonus = bonus;
      }
      
      public Long getId() {
        return id;
      }
      public void setId(Long id) {
        this.id = id;
      }
      public String getName() {
        return name;
      }
      public void setName(String name) {
        this.name = name;
      }
      public Double getBonus() {
        return bonus;
      }
      public void setBonus(Double bonus) {
        this.bonus = bonus;
      } 
      
    }

    9.泛型的意义

      减少强制类型转换的使用

    更多内容,请关注:http://www.cnblogs.com/BlueStarWei/

  • 相关阅读:
    创建内核对象的专有命名空间
    内核对象句柄表
    Windows小知识(二)
    内核对象与用户对象/GDI对象
    Windows小知识(一)
    Windows中查看错误
    handle(句柄)
    VC中调用其它程序
    消息映射的转变
    实验6.配置链路聚合
  • 原文地址:https://www.cnblogs.com/BlueStarWei/p/7622207.html
Copyright © 2011-2022 走看看