zoukankan      html  css  js  c++  java
  • 泛型编程-2

    上一篇 介绍了泛型最基本的用法,泛型类和泛型方法。

    这篇将继续慢慢的解开泛型的面纱。

    类型限定

    有的时候方法或者类为了一些需求需要对泛型的的类型做出 一些限定。

    假如:有一个类对象ArrayList中的的每一个元素实现了AutoCloseable,想要把他们全部关闭,可以如下写

      public static  <T extends AutoCloseable> void clossAll(ArrayList<T> elems)throws Exception{
            for (T elem : elems) {
                elem.close();
            }
        }

    类型的变异和通配符

    备用实体:

    //
    public class Perion {}
    
    //雇员
    public class Employee extends  Perion{}
    
    //其他
    public class Employee extends  Perion{}
    
    //经理
    public class Manager extends Employee {}

    子类通配符

     /**
         * 读取ArrayList<? extends Employee>  对象中的每一个元素
         * @param staffs
         */
        public static void printName(ArrayList<? extends Employee> staffs){
            for (int i = 0; i < staffs.size();i++){
                Employee employee = staffs.get(i);
                System.out.println(employee.getName());
            }
        }
    
        /**
         * 修改操作
         * 错误实例 不能编译通过
         * add(capture<? extends genericity.gen4.Employee>)in ArrayList cannot be applied to (genericity.gen4.Employee)
         * @param staffs
         */
        public static void add(ArrayList<? extends Employee> staffs){
            Employee employee = new Employee("15", "测试");
            staffs.add(employee);
        }

    通过上面两个例子可以总结:可以将 <? extends Employee>转化成Employee但是不能将任何对象转化成Employee。可以限定返回值。可读。

    父类型通配符

     /**
         * 父类通配符
         * @param employees
         */
        public static void add2(ArrayList<? super Employee> employees){
            Employee e = new Employee();
            Manager m = new Manager();
            employees.add(e);
            employees.add(m);
            //不能变译通过
          //  employees.add(new Other());
        for (int i = 0;i < employees.size();i++){
    //super 不能限制返回值 所以必须Object
    Object obj = employees.get(i);
    }
    } public static void main(String[] args) { ArrayList<? super Employee> es = new ArrayList<Employee>(); //不能变译通过 // List<? super Employee> es2 = new ArrayList<Manager>(); add2(es); }

    可以看出super 可用于参数类型限定,不能用于返回类型限定。参数限定于Employee主干上。可写。

    无限定通配符

        /**
         * 无限定通配符
         */
        public static boolean hasNulls(ArrayList<?> elements){
            for (Object element : elements) {
                if(element == null){
                    return true;
                }
            }
            return  false;
        }

    在某些情况下需要作非常通用的功能,可能会用到无限定通配符,如上检查ArrayList是否包含null值元素,由于ArrayList的类型是无关紧要的,所以使用ArrayList<?>完全可以。

    带类型变量的通配符

      /**
         * 带类型变量的通配符
         *限制Predicate的参数和方法的类型参数完全匹配 ? super T
         * @param elements
         * @param filter
         * @param <T>
         */
        public static <T> void printAll2(T[] elements ,Predicate<? super T> filter){
            for (T e : elements) {
                if(filter.test(e)){
                    System.out.println(e.toString());
                }
            }
        }
    public interface Predicate<T> {
    
        /**
         *
         * @param arg
         * @return
         */
        boolean test(T arg);
    }

    可以看出统配的限定是一个类型的变量。

  • 相关阅读:
    B
    给定二叉树先序、中序遍历序列,求后序遍历
    24点游戏dfs求解
    设计模式之单例模式
    生产者—消费者模式示例
    LeetCode(3):Longest Substring Without Repeating Characters
    LeetCode(5):Longest Palindromic Substring
    LeetCode(60):Permutation Sequence
    LeetCode(50):Pow(x,n)
    LeetCode(69):Sqrt(x)
  • 原文地址:https://www.cnblogs.com/java-gaolei/p/8284036.html
Copyright © 2011-2022 走看看