美文网首页程序员
Android 开发也要掌握的Java知识 - Java泛型

Android 开发也要掌握的Java知识 - Java泛型

作者: 进击的包籽 | 来源:发表于2020-07-28 10:40 被阅读0次

    如果需要看泛型擦除Java泛型擦除

    1.Java泛型有什么用?为啥要使用泛型?

    • Java中数组的类型是定义的时候就写死了,后面添加数据的时候,就必需是定义好的类型,这样要求严格的好处就是不会出错,不会再后面使用时出错。
    • 而使用List,可以用Object对象(不定义类型或者是定义Object类型),这样什么都能往里面放,但是使用的时候,遍历的时候,要么出现类型转化异常,要么每个都判断类型。
    • 使用List的时候,如果定义时写的是String,那么后面使用,就自动会帮你判断是否是String类型,是才能存入数据,拿出是也一定是String。Java提供编译时类型安全监测机制:泛型,不用强转,存放的类型也指定了,不会出错(ClassCastException)。
    • 使用泛型代码更整洁,更灵活,能复用

    2.泛型通配符

    • 泛型中的通配符:T,K,V,E,?,其实你想写啥都行,写在<>先括号里
    • 一般T表示类型type
    • K,V配合,表示key,value
    • E表示元素Element
    • ?无界通配符,就是啥类型都行
    上下界.png
    • 上界限通配符 < ? extends E>,比如 父类:Animal,子类:Cat,子类的子类:MiniCat,写了<? extends Cat>,就能传Cat跟MiniCat,不能传Animal。
    public Fan() {
          List<Animal> animas = new ArrayList<>();
          List<Cat> cats = new ArrayList<>();
          List<MiniCat> miniCats = new ArrayList<>();
     
         // setList(animals);
          setList(cats);
          setList(miniCats);
    }
     
    /**
       * MiniCat extends Cat extends Animal
       * 通配符 super 决定了下限,只要是Cat或者是Cat继承了类都可以填入
       *
       * @param list
    */
    public static void setList(List<? extends Cat> list) {
     
     }
    
    • 下界限通配符 < ? super E>,比如 父类:Animal,子类:Cat,子类的子类:MiniCat,写了<? super Cat>,就能传Cat跟Animal,不能传MiniCat
    public Fan() {
          List<Animal> animals = new ArrayList<>();
          List<Cat> cats = new ArrayList<>();
          List<MiniCat> miniCats = new ArrayList<>();
     
          setList(animals);
          setList(cats);
          //setList(miniCats);
    }
     
    /**
       * MiniCat extends Cat extends Animal
       * 通配符 super 决定了下限,只要是Cat或者是Cat继承了类都可以填入
       *
       * @param list
    */
    public static void setList(List<? superCat> list) {
     
     }
    
    • 下界通配符使用,比如TreeSet


      TreeSet.png
    public static void comparatorAnimal() {
        /*TreeSet内部比较
        TreeSet(Comparator<? super E> comparator)
        用Comparator1就是比较name
        用Comparator2就是比较age
        */
        Set<Cat> catSet = new TreeSet<>(new Comparator1());
        catSet.add(new Cat("bao6", 1));
        catSet.add(new Cat("bao1", 5));
        catSet.add(new Cat("bao2", 3));
        catSet.add(new Cat("bao5", 6));
        catSet.add(new Cat("bao4", 2));
    
        for (Cat cat : catSet) {
            Log.d("baozi", cat.toString());
        }
    }
    
    /**
     * 对比name
     */
    static class Comparator1 implements Comparator<Anima> {
        @Override
        public int compare(Anima o1, Anima o2) {
            return o1.name.compareTo(o2.name);
        }
    }
    
    /**
     * 对比age
     */
    static class Comparator2 implements Comparator<Cat> {
        @Override
        public int compare(Cat o1, Cat o2) {
            //比较参数
            return o1.age - o2.age;
        }
    }
    
    /**
     * 对比num,这里就不能用Comparator3 ,因为是<? super E >
     */
    static class Comparator3 implements Comparator<MiniCat> {
        @Override
        public int compare(MiniCat o1, MiniCat o2) {
            return o1.num - o2.num;
        }
    }
    
    Comparator1 .png Comparator2 .png

    3.泛型怎么写,规则有哪些

    • 如果类定义了泛型,就不能写静态的泛型返回方法
    • 泛型方法跟泛型类没有关系,可以同时使用T也是可以的,不会影响
    public class Fan<T> {
        private T t;
     
        public Fan(T t) {
            this.t = t;
        }
     
        public T getT() {
            return t;
        }
     
        /**
         * 泛型不能用静态方法,因为类初始化没声明泛型
         *
         * @param t
         */
        public void setT(T t) {
            this.t = t;
        }
     
        /**
         * 泛型方法里面的T不受外部类T的影响
         * 所以可以用静态
         *
         * @param t
         * @param <T>
         */
        public static <T> void setT2(T t) {
        }
    }
    
    • 泛型继承关系
    class Father<K, V> {
    }
    
    /**
     * 子类不是泛型什么都不写
     * 等价于Child extends Father<Object,Object>
     */
    class Child1 extends Father {
    }
    
    /**
     * 子类不是泛型,父类写上具体类型,而且有几个写几个
     */
    class Child2 extends Father<Integer,String>{
    }
    
    /**
     * 子类完全保留了父类的泛型
     * @param <K>
     * @param <V>
     */
    class Child3<K, V> extends Father<K, V> {
    }
    
    /**
     * 子类保留了部分父类的泛型,但是另一个必需写
     * @param <V>
     */
    class  Child4<V> extends Father<String,V>{
    }
    
    /**
     * 子类比父类更多泛型
     * @param <T>
     * @param <K>
     * @param <V>
     */
    class Child5<T,K,V> extends Father<K,V>{
    }
    
    • 泛型接口
    
    /**
     * 泛型接口
     * @param <E>
     */
    interface Man<E> {
        void setData(E e);
    
        E getData();
    }
    
    /**
     * 不写具体参数,默认就是Object
     */
    class MiniMan implements Man{
        @Override
        public void setData(Object o) {
    
        }
    
        @Override
        public Object getData() {
            return null;
        }
    }
    
    /**
     * 写具体类型
     */
    class BigMan implements Man<String>{
        @Override
        public void setData(String s) {
    
        }
    
        @Override
        public String getData() {
            return null;
        }
    }
    
    • 泛型可以写数组吗?
    public class TestArray<T> {
        //不能声明带泛型的数组,因为数组类型在创建时就确定要类型了
        //T[] tList = T[5];
     
        //可以这样定义
        private ArrayList<String>[] arrayLists = new ArrayList[5];
         
        private T[] array;
     
        public TestArray(Class<T> clz,int length) {
            array = (T[]) Array.newInstance(clz,length);
        }
     
        public T getData(int index){
            return array[index];
        }
     
        public void put(int index,T item){
            array[index] = item;
        }
     
        public T[] getArray(){
            return array;
        }
    }
    
    TestArray<String> testArray = new TestArray<>(String.class, 5);
    testArray.put(0, "baozi0");
    testArray.put(2, "baozi2");
    testArray.put(1, "baozi1");
    testArray.put(4, "baozi4");
    testArray.put(3, "baozi3");
    

    4.参考文章

    Java中的泛型方法
    哔哩哔哩视频

    如果有写的不对,希望大家帮忙指出错误,谢谢!

    相关文章

      网友评论

        本文标题:Android 开发也要掌握的Java知识 - Java泛型

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