• java 泛型


    在我看来,java的泛型一直就是语法糖,就是帮助我们在写代码的时候不会抛出java.lang.ClassCastException异常,看代码

     1 public class GenericTest {
     2 
     3     public static void main(String[] args) {
     4         List list = new ArrayList();
     5         list.add("a");
     6         list.add("b");
     7         list.add(100);
     8 
     9         for (int i = 0; i < list.size(); i++) {
    10             //下面代码编译时肯定 没错,运行就会报错
    11             String name = (String) list.get(i); 
    12             System.out.println("name:" + name);
    13         }
    14     }
    15 }

    你创建List的时候没有指定它的类型,那就是默认的Object,添加任何类型都没问题,遍历的时候要打印转换时,全部转String肯定报错,因为之前添加有int,所以这时候如果我们一开始加泛型,那添加的时候就会告诉我们,List里存储的是同一种类型

    泛型,即“参数化类型”。一提到参数,最熟悉的就是定义方法时有形参,然后调用此方法时传递实参。那么参数化类型怎么理解呢?顾名思义,就是将类型由原来的具体的类型参数化,类似于方法中的变量参数,此时类型也定义成参数形式(可以称之为类型形参),然后在使用/调用时传入具体的类型(类型实参)。再看代码

    public class GenericTest {
    
        public static void main(String[] args) {
          
            List<String> list = new ArrayList<String>();
            list.add("a");
            list.add("b");
            //  提示编译错误
            //list.add(100);   
    
            for (int i = 0; i < list.size(); i++) {
                String name = list.get(i); // 这边就不需要转换,因为里面的类型都是String
                System.out.println("name:" + name);
            }
        }
    }    

    查看集合类的源码都是加泛型的,这样我们再执行一些操作的时候能确保集合里都是同一种“类型”

    在泛型接口、泛型类和泛型方法的定义过程中,我们常见的如T、E、K、V等形式的参数常用于表示泛型形参,由于接收来自外部使用时候传入的类型实参。

    知道这些后我们自己来实现一下泛型

     1 public class Test {
     2 
     3     public static void main(String[] args) {
     4 
     5         //创建一个实体类,调用带参构造函数函数传个值  
     6         Container<String> name = new Container<String>("abc");
     7         //上面已经定义了Container里只能放String类型
     8         System.out.println("name:" + name.getData());
     9     }
    10 
    11 }
    12 
    13 //自定义一个类,当作容器,里面可以放任何类型的实体
    14 class Container<T> {
    15 
    16     private T data;
    17 
    18     public Container(T data) {
    19         this.data = data;
    20     }
    21 
    22     public T getData() {
    23         return data;
    24     }
    25 
    26 }

    再看下面代码输出

    1     Container<String> container1 = new Container<String>("a");
    2         Container<Integer> container2 = new Container<Integer>(100);
    3         System.out.println(container1.getClass());
    4         System.out.println(container2.getClass());
    5         Boolean bl = container1.getClass() == container2.getClass();
    6         System.out.println(bl);

    输出:

    class Container
    class Container
    true

    不管他们规定的是String类型还是Integer,编译过后的container1 和container2都是Container类型的,所以一开始说泛型只是语法糖~压根没有变

    最后来看这段代码

    class Test {
    
        public static void main(String[] args) {
    
            Container<String> name = new Container<String>("abc");
            Container<Integer> age = new Container<Integer>(100);
            Container<Number> number = new Container<Number>(200);
            Container<Float> ft = new Container<Float>(200F);
    
    
            getData(name);
            getData(age);
            getData(number);
    
            // 报错
            //getUpperNumberData(name);
            getUpperNumberData(age);
            getUpperNumberData(number);
    
            getUpperNumberData(age);
            //报错
            //getDownNumberData(ft);
    
        }
    
        public static void getData(Container<?> data) {
            System.out.println("data :" + data.getData());
        }
    
        public static void getUpperNumberData(Container<? extends Number> data) {
            System.out.println("data :" + data.getData());
        }
    
        public static void getDownNumberData(Container<? super Integer> data) {
            System.out.println("data :" + data.getData());
        }
    
    }

    类型通配符一般是使用 “?”代替具体的类型实参。此处是类型实参,而不是类型形参。有时候类型通配符还分上限和类型通配符下限

    类型通配符上限通过形如Container<? extends Number>形式定义,相对应的,类型通配符下限为Container<? super Number>形式,其含义与类型通配符上限正好相反

  • 相关阅读:
    【转】ServletContext介绍及用法
    【转】UML之类图和对象图
    【转】UML各种图总结
    解决win10下 matplotlib绘图时中文乱码问题
    修改表、字段的默认字符集
    MySQL报错Incorrect date value: '0000-00-00' for column 'hirrdate' at row 1
    用vs code将qt designer的.ui文件转换为.py文件
    MySQL多表数据查询记录
    MySQL中统计函数和分组数据查询
    lambda匿名函数
  • 原文地址:https://www.cnblogs.com/hzzjj/p/7275058.html
Copyright © 2020-2023  润新知