美文网首页
java泛型

java泛型

作者: 小左伯爵 | 来源:发表于2020-11-15 22:34 被阅读0次

    1.为什么要有泛型

    1.1什么是泛型

    • 泛型:标签
      举例:中药店,每一个盒子(抽屉)都有一个标签写着中药名,盒子(抽屉)就相当于一个容器,就像java中的集合一样
    • 泛型的设计背景
      集合容器类在设计阶段/声明阶段不能确定这个容器到底实际存储的时什么类型的对象,所以jdk1.5之前只能把元素类型设计为Object,jdk1.5之后是使用泛型来解决,因为这个时候除了元素的类型不确定,其他部分都是确定的,例如关于这个元素如何保存,如何管理是确定的,因此此时把元素的类型设计成一个参数,这个类型参数叫做泛型,Collection<E>,List<E>这个<E>就是类型参数,即泛型

    1.2不加泛型会存在哪些问题

    • 类型不安全
    • 出现ClassCastException
    package com.ruoyi.web.message.test;
    
    import java.util.ArrayList;
    
    /**
     * @author chenxiaogao
     * @className GenericDemo
     * @description 不使用泛型产生的问题
     * @date 2020/11/15
     **/
    public class GenericDemo {
        public static void main(String[] args) {
            //需求:存放学生成绩
            ArrayList scoreList = new ArrayList();
            scoreList.add(55);
            scoreList.add(66);
            scoreList.add(88);
            //问题1:类型不安全
            scoreList.add("tom");
            for (Object score : scoreList) {
                //问题2:出现ClassCastException
                //ClassCastException
                int stuScore = (int)score;
                System.out.println("stuScore = " + stuScore);
            }
    
        }
    }
    

    1.3使用泛型

    //2.使用泛型
            ArrayList<Integer> scoreList1 = new ArrayList<>();
            scoreList1.add(66);
            scoreList1.add(67);
            scoreList1.add(68);
    //编译报错,避免了类型错误
            scoreList1.add("jd");
    //避免了类型转换,不会发生类型转换异常
    for (Integer integer : scoreList1) {
                System.out.println("integer = " + integer);
            }
    

    1.4总结

    • 集合接口或结合类在jdk5.0时都修改为带泛型的结构。
    • 在实例化集合类时,可以指明具体的泛型类型
    • 指明完以后,在集合类或接口中凡是定义接口或类时,内部结构(方法,构造,属性等)使用到类的泛型的位置,都指定为实例化的泛型类型;例如:add(E e) 实例化后 add(Integer e)
    • 泛型的类型必须是一个类,基本数据类型用包装类
      +如未指定泛型,则默认为Object

    2.自定义泛型结构(泛型类,泛型接口,泛型方法)

    • 自定义泛型类
    package com.ruoyi.web.message.test;
    
    /**
     * @author chenxiaogao
     * @className Order
     * @description 自定义泛型类
     * @date 2020/11/15
     **/
    public class Order<T> {
        String orderName;
    
        T orderT;
    
        public String getOrderName() {
            return orderName;
        }
    
        public void setOrderName(String orderName) {
            this.orderName = orderName;
        }
    
        public T getOrderT() {
            return orderT;
        }
    
        public void setOrderT(T orderT) {
            this.orderT = orderT;
        }
    }
    
    • 在实例化Order时就可以动态指定orderT的类型
    public class GenericDemo {
        public static void main(String[] args) {
            Order<String> strOrder = new Order<>();
            strOrder.setOrderT("hello");
            String orderT = strOrder.getOrderT();
            System.out.println("orderT = " + orderT);
    
    
            Order<Integer> intOrder = new Order<>();
            intOrder.setOrderT(1);
            Integer orderT1 = intOrder.getOrderT();
            System.out.println("orderT1 = " + orderT1);
        }
    }
    
    • 子类在继承带泛型的父类时,若父类指明了类型,则子类不需要再指定
    package com.ruoyi.web.message.test;
    
    /**
     * @author chenxiaogao
     * @className SubOrder1
     * @description TODO
     * @date 2020/11/15
     **/
    public class SubOrder1 extends Order<Integer> {
    }
    
    • 子类在继承带泛型的父类时,若父类使用泛型,则子类也需要为泛型
    package com.ruoyi.web.message.test;
    
    /**
     * @author chenxiaogao
     * @className SubOrder
     * @description TODO
     * @date 2020/11/15
     **/
    public class SubOrder<T> extends Order<T> {
    }
    
    
      1. 泛型类可能有多个参数,此时应将多个参数一起放到<>中
    public class HashMap<K,V> extends AbstractMap<K,V>
        implements Map<K,V>, Cloneable, Serializable {}
    
    • 2.泛型类的构造如下
    public Order() {
            
        }
    而不是
    public Order<>() {
            
        }
    
    • 3.实例化后,操作原来泛型位置的结构(方法,构造,属性)必须与指定的类型一致;
    • 4.泛型不同的引用不能相互赋值
     public static void main(String[] args) {
           //这样是不行的
            ArrayList<Integer> integers = null;
            ArrayList<String> strings = null;
            integers = strings;
            //这样可以
            ArrayList<String> str1 = null;
            ArrayList<String> str2 = null;
            str1 = str2;
        }
    
    • 5.泛型如果不指定,将被擦除,泛型对应的类型均按照Object处理,但不等价与Object
    • 6.jdk1.7,泛型简化 ArrayList<String> list = new ArrayList<>();
    • 7.泛型的指定不能使用基本数据类型,可以使用包装类型替代
    • 8.在类/接口上声明的泛型,不能在静态方法中使用,因为使用泛型是在类的实例化时确定的,而静态方法不需要实例化该类便可调用;
    • 9.异常类不能时泛型的
      +10.不能使用new E[];

    3.自定义泛型方法

    • 在方法中出现泛型结构,泛型参数与类的泛型参数没有任何关系,即泛型方法可以存在于泛型类中,也可以存在于非泛型类中
    public <E> List<E> copyArrayToList(E[] array) {
            List<E> list = new ArrayList<>();
            for (E e : array) {
                list.add(e);
            }
            return list;
        }
    

    使用

    public class GenericDemo {
        public static void main(String[] args) {
    
            Order<String> strOrder = new Order<>();
            Integer[] array = {1, 2, 3};
    
            List<Integer> list = strOrder.copyArrayToList(array);
            String s = list.toString();
            System.out.println("s = " + s);
    
        }
    }
    
    
    • 泛型方法可以为静态方法,因为方法的泛型为调用该方法时确定的,并非在实例化时确定的
    public static  <E> List<E> copyArrayToList(E[] array) {
            List<E> list = new ArrayList<>();
            for (E e : array) {
                list.add(e);
            }
            return list;
        }
    

    4.通配符的使用

    package com.ruoyi.web.message.test;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.Iterator;
    import java.util.List;
    
    /**
     * @author chenxiaogao
     * @className GenericDemo
     * @description 通配符的使用
     * @date 2020/11/15
     **/
    public class GenericDemo {
        public static void main(String[] args) {
    
            List<Object> list1= null;
            List<String> list2 =null;
    
            List<?> list = null;
    
            list = list1;
            list = list2;
    
    
    
        }
    
        public static void print(List<?> list) {
            Iterator<?> iterator = list.iterator();
            while (iterator.hasNext()) {
                Object next = iterator.next();
                System.out.println(next);
    
            }
        }
    }
    
    
    • 有限制条件的通配符
    public class GenericDemo {
        public static void main(String[] args) {
    
            List<? extends Person> list1 = null;
            List<? super Person> list2 = null;
            
            List<Person> list3 = null;
            List<Student> list4 = null;
            List<Object> list5 = null;
            
            list1 = list3;
            list1 = list4;
        //list5无法赋值给list1
            list1 = list5;//报错
    
            list2 = list3;
            list2 = list4;//报错
            list2 = list5;
    
    
    
           
    
    
        }
    
        
    }
    
    

    相关文章

      网友评论

          本文标题:java泛型

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