• java泛型整理


    背景:

    类型转换中的ClassCastException,JDK5引入,JDK7后<>中的类型可以省略

    泛型的本质是为了参数化类型(在不创建新的类型的情况下,通过泛型指定的不同类型来控制形参具体限制的类型)。
    也就是说在泛型使用过程中,操作的数据类型被指定为一个参数,这种参数类型可以用在类、接口和方法中,分别被称为泛型类、泛型接口、泛型方法。

    好处:

    编译时类型检查保证类型安全,消除强制类型转换,代码复用

    定义泛型类

    /**
     * 泛型类的定义语法:
     * class ClassName <泛型标识1,泛型标识2,泛型标识3...>{
     *     private 泛型标识 变量名
     * }*/
    public class Generic<T>{
    
        /**
         * 常用的泛型标识有T,E,K,V
         */
        private T key;
    
        public Generic(T key) {
            this.key = key;
        }
    
        public T getKey() {
            return key;
        }
    
        @Override
        public String toString() {
            return "Generic{" +
                    "key=" + key +
                    '}';
        }
    }

    使用泛型类

           /**
             * 使用语法:
             * 类名<具体数据类型>  对象名 = new 类名<>();
             * 泛型是在创建对象的时候,来指定操作的具体类型
             * 不支持基本数据类型,只支持引用类型
             * 如果不指定具体的数据类型,默认是Object类型
             * 不同类型创建的泛型对象,都是相同的类型,与泛型类型无关,也就是getClass()结果相同
             *
             */
            Generic<String> strGeneric = new Generic<>("a");
            Generic<Integer> intGeneric = new Generic<>(1);
            System.out.println(strGeneric.getClass()==intGeneric.getClass());   ---true

     泛型类的子类

    子类如果也是泛型类,子类和父类泛型类型要一致;因为子类加载前要先加载父类,如果不一致,父类不清楚是什么类型,会直接报错,无法加载

    子类如果也是泛型类,至少要有一个和父类泛型类型一致,子类还可以有多个泛型类型

    子类如果不是泛型类,父类要指定具体的泛型类型;

    public class Parent<E> {
        private E value;
    
        public E getValue() {
            return value;
        }
    }
    /**
     * 父类不指定类型,则默认泛型类型是Object
     */
    public class Child1<T> extends Parent{
        /**
         * 返回的是Object
         */
        @Override
        public Object getValue() {
            return super.getValue();
        }
    }
    
    /**
     * 子类是泛型,那么子类和父类的泛型类型必须一致
     * 子类可以有多个泛型类型
     */
    public class Child1<E,T,K> extends Parent<E>{
    
        @Override
        public E getValue() {
            return super.getValue();
        }
    }
    
    /**
     * 子类不是泛型类,父类必须明确数据类型
     * 因为加载子类的时候需要先加载父类,父类不知道是什么类型,加载报错
     */
    public class Child2 extends Parent<E>{  --------报错
    
        @Override
        public E getValue() {
            return super.getValue();
        }
    }

    泛型接口

    和泛型类相似,定义语法:

    interface 接口名称<泛型标识1,泛型标识2,泛型标识3>{
        泛型标识  方法名();
    }

    实现类如果是泛型类,实现类和接口的泛型类型要一致

    实现类如果不是泛型类型,接口要明确泛型类型

    例子和泛型类的差不多

    泛型方法

    语法:

    修饰符 <T,K,E...> 返回类型  方法名(参数列表){
        方法体
    }

    找到一张很好的图:

    以<T>为例

    修饰符和返回类型之间的<T>声明此方法是泛型方法,只有声明了<T>的方法才是泛型方法

    泛型类中使用了泛型类型的方法不是泛型方法(因为这个泛型类型其实只是返回类型)

    <T>表明该方法将使用泛型类型T,此时才可以在泛型方法中使用类型T

       /**
         * 泛型方法
         * @param list  参数
         * @param idx   参数
         * @param <E>   泛型方法的标识,具体类型由调用方法的时候来指定
         * @return
         */
        public <E> E getProduct(ArrayList<E> list,int idx){
            return list.get(idx);
        }

     类型通配符

    类型通配符就是能代表任意类型的一个符号,比如 ?

    @Data
    public class Box<E>{
        private E ball;
    }
    
    public class Test {
    
        public static void main(String[] args) {
            Box<Number> box1 = new Box<>();
            box1.setBall(100);
            showBox(box1);
    
            //Integer继承的Number,也不能直接调用
            Box<Integer> box2 = new Box<>();
            box2.setBall(100);
            //报错
            showBox(box2);   
        }
    
        public static void showBox(Box<Number> box){
            Number ball = box.getBall();
            System.out.println(ball);
        }
    }

    类型通配符上限

    语法:<? extends 实参类型>

    表示使用时泛型的类型只能是实参类型或它的子类类型

    public class Test {
    
        public static void main(String[] args) {
            ArrayList<A> listA = new ArrayList<A>();
            ArrayList<B> listB = new ArrayList<B>();
            ArrayList<C> listC = new ArrayList<C>();
            //报错
            print(listA);
            print(listB);
            print(listC);
    
        }
    
        public static void print(ArrayList<? extends B> list){
            //do something
        }
    }

    类型通配符下限

    语法:<? super 实参类型>

    表示使用时,泛型类型只能是实参类型或它的父类类型

    /**
     * 假设类  C extends B extends A
     */
    public class Test {
    
        public static void main(String[] args) {
            ArrayList<A> listA = new ArrayList<A>();
            ArrayList<B> listB = new ArrayList<B>();
            ArrayList<C> listC = new ArrayList<C>();
            print(listA);
            print(listB);
            //报错
            print(listC);
    
        }
    
        public static void print(ArrayList<? super B> list){
            //do something
        }
    }

     类型擦除

    无限制类型的情况下擦除后是Object类型,也就是泛型类型的根父类

    public class Box<E>{
        
        private E ball;
    
        public E getBall() {
            return ball;
        }
    
        public Box(E ball) {
            this.ball = ball;
        }
    }
    ///////////类型擦除的结果///////////////
    public class Box {
    
        private Object ball;
    
        public Object getBall() {
            return ball;
        }
    
        public Box(Object ball) {
            this.ball = ball;
        }
    }

    上限通配符情况下,擦出后是上限类型

    public class Eraser<T extends Number> {
        
        private T key;
    
        public T getKey() {
            return key;
        }
    
        public Eraser(T key) {
            this.key = key;
        }
    }
    
    /////////////类型擦除后////////////////
    public class Eraser{
    
        private Number key;
    
        public Number getKey() {
            return key;
        }
    
        public Eraser(Number key) {
            this.key = key;
        }
    }

     泛型方法的类型擦除

       public <T extends Number> T getValue(T value){
           return value;
       }
      ///////类型擦除后/////////////
       public Number getValue(Number value){
           return value;
       }

     反射常用的泛型类

    Class<T>

    Constructor<T>

     

  • 相关阅读:
    会议总结
    排球比赛积分规则
    我的计算机历程和认识
    排球积分程序
    《如何成为一个高手》观后感
    十八周总结
    十六周总结(流程)
    排球计分程序
    十四周学习总结
    十三周学习总结
  • 原文地址:https://www.cnblogs.com/yb38156/p/16079681.html
Copyright © 2020-2023  润新知