什么是泛型、泛型使用场景?

 2022-09-07
原文地址:https://blog.51cto.com/u_14523732/5633657

什么是泛型

泛型类:具有一个或多个类型变量的类,称为泛型类。
泛型方法:具有一个或多个类型变量的方法,称之为泛型方法。

  • 泛型是一种未知的类,将未知的类声明在集合、对象上,泛型默认为Object。
  • 使用泛型可以在传参的时候不固定传入什么类型,即可通用类型。
  • 使用泛型后,集合或对象上只能放入指定的数据类型,可以保证对象或集合的安全性,减少类型的转换操作。

类型安全:

  • 泛型的主要目标是提高Java程序的类型安全
  • 编译时期就可以检查出因Java类型不正确导致的ClassCastException异常
  • 符合越早出错代价越小原则。
    消除强制类型转换:
  • 泛型的一个附带好处是,使用时之恶杰得到目标类型,消除许多强制类型转换。
  • 所得即所需,这使得代码更加可读,并且减少了出错机会。
  • 由于泛型的实现方式,支持泛型(几乎)不需要 JVM 或类文件更改
  • 所有工作都在编译器中完成
  • 编译器生成的代码跟不使用泛型(和强制类型转换)时所写的代码几乎一致,只是更能确保类型安全而已

泛型使用场景

泛型类、泛型方法、泛型接口、泛型通配符。
泛型类:
指定类内部成员变量的数据类型。

    /**
     * 声明在类上时,写在类名后边
     * @param <E>
     */
    class Animal <E> {
        /**
         * 作为属性声明时,必须在类上声明泛型
         */
        E pet;
    
        /**
         * 作为参数或者返回值时,如果在类上没有声明,必须在访问修饰符和返回值之间
         * @param pet
         */
        public  void setPet(E pet){
            this.pet = pet;
        }
    
        public E getPet(){
            return pet;
        }
    
        public <T> void call(T t){
            System.out.println( t.toString() );
    
        }
    
    }

泛型接口:

    /**
     * 作用在接口上,如果实现该接口时指定实现类型
     * @param <T>
     */
    public interface Animals<T>{
        void call(T t);
    }
    /**
     * 拉布拉多犬
     */
    
    /**
     * 使用泛型实现时,实现类必须使用对应的泛型类。
     * 实现类声明泛型跟接口指定泛型可以同时使用。
     *如下代码:
     */
     class LaBuLaDuo<T> implements Animals<String> {
    
        public void call(String s) {
            System.out.println( s );
        }
    
    }

泛型占位符

    /**
     * 小狗狗
     */
     class Dog extends  Animal {
        public String name;
        public Integer age;
    
    }
    
    
    /**
     * 泛型占位符  ?  的使用
     * 泛型的上限 < ? extends E>  即传入参数必须为E 的子类
     * 泛型的下限 < ? super E>
     */
    public class ErHa <E>  {
    
        //当参数传递时可以设置上下限 比如下面的是  传入类型必须是 Dog 的子类,上限为Dog
        public  void call(Animal< ? extends E> s){
            System.out.println(s.pet);
        }
    
        //传入类型必须是 Dog 的父类,下限为Dog
        public  void jump(Animal< ? super E> s){
            System.out.println(s.pet);
        }
    
        // ? 占位符单独使用时,相当于 < ? extends Object >
        public  void smile(Animal<?> s){
            System.out.println(s.pet);
        }
    
    
        public static void main(String[] args) {
            new ErHa<Dog>().call(new Dog());
        }
    }