• java中的泛型


    知识点:

         泛型的概念

         泛型类,泛型接口,泛型方法

         通配符

     ? extend A:可以引用A以及子类,只可以存放null     
    ? super A:可以引用A以及父类,可以存放A以及A的子类

    参考博客:https://www.cnblogs.com/lwbqqyumidi/p/3837629.html
    https://mp.weixin.qq.com/s?__biz=MzIxNzQwNjM3NA==&mid=2247485714&idx=1&sn=7839a7caf10399d59a6a46e9bc5668cd&chksm=97fb07dba08c8ecd5da21ae1f3cede4912f81672ef20d35d840d6a7889abb337c214ac7b9579&scene=0&xtrack=1&key=b2d158037147950fd504ba5526dd4c3f7dd6abf9bde19a33a1abf6e826e1f1c7600f6b07fd9d1905e8125e47c0984426c7ff9b894ff5ef3bf42a04574e4f4f3fe6bdb84178f4acfb2117122a61da2a21&ascene=14&uin=MjEzMzY3MzkzNA%3D%3D&devicetype=Windows+10&version=62060739&lang=zh_CN&pass_ticket=1kSdouT4BHYceycY9n%2FLFiQUOaQQc%2FwAunx2nhzC7rjp%2FsScflTyHbyH3JczQ6hL&winzoom=1

    一:什么是泛型,为什么使用方式泛型

    (1)什么是泛型

       把一个集合中的内容限制为一个特定的数据类型

    (2)为什么使用泛型

    先看一下一个例子:

    public class genTest {
    public static void main(String[] args) {
    List list=new ArrayList();
    list.add("AA");
    list.add("BB");
    list.add(12);
    for (int i=0;i<list.size();i++){
    String name=(String)list.get(i);//类型转换
    System.out.println(name);
    }
    }
    }

    上面程序会报类型转化异常

    原因:上面的代码中,我们定义了一个list集合,分别向集合中加入String,Integer两种类型的数据,这是list会默认都转为Object类型元素,在循环时,Integer类强转成String类型的元素,会报错类型转换异常的错误,这种错误在编译阶段不会显示,只有在运行阶段才会出现

    上面再编译阶段不显示错误,是因为list并不清楚自己的存的元素类型,在遍历取出元素时,默认把元素编译改成Object的类型,但是运行时,时元素本身的类型,如果我们让集合一开始存数据时,就知道自己存的数据类型,那么在编译期间可以避免这种错误,泛型就很好解决了这种问题

    上面的程序可以这样改一下(加泛型List<String> list=new ArrayList<>();

    二:泛型类,泛型接口,泛型方法

    泛型类,泛型接口是传入一个不确定的对象类型,根据实际传入的不同对象,调用相同的方法(在接口,类后面加<E>其中E可以随便定义T,F等等)

    泛型方法:方法参数中加入泛型,可以传入不同的类型的对象(在返回值前面加<T>)

    //泛型类
    public class Parent<E> {
    private String name;
    private E e;
    public Parent(){
    }
    public String getName() {
    return name;
    }
    public void setName(String name) {
    this.name = name;
    }
    public E getE() {
    return e;
    }
    public void setE(E e) {
    this.e = e;
    }
    //声明泛型方法
    public <T> T getT(T t){
    return t;
    }
    //实现数组到集合的复制
    public <T> List<T> fromArrayToList(T[] t, List<T> list){
    for (T t1:t){
    list.add(t1);
    }
    return list;
    }
    }

    测试类
    public class Children<E> extends Parent<E> {
    @Test
    public void Testgenericity1(){
    //泛型类,泛型方法
    Children c=new Children();
    c.setE("AA");
    System.out.println(c.getE());
    c.setE(12);
    System.out.println(c.getE());

    //泛型方法
    Boolean b1=(Boolean)(c.getT(true));
    System.out.println(b1);
    Double d1=(Double) (c.getT(11.1));
    System.out.println(d1);

    String[] strarr=new String []{"AA","BB","CC"};
    List<String> list=new ArrayList<>();
    List<String> list1=c.fromArrayToList(strarr,list);
    System.out.println(list1);

    Integer[] strarr1=new Integer[]{11,22,33};
    List<Integer> list2=new ArrayList<>();
    List<Integer> list3=c.fromArrayToList(strarr1,list2);
    System.out.println(list3);
    }
    }
    运行结果:


    三:通配符 ?

    (1)统配符的使用
    @Test
    public void Testgenericity3(){
    //通配符的使用
    List<String> list=new ArrayList<>();
    list.add("AA");
    list.add("BB");
    List<?> slist=list;
    //可以读取声明为统配符的集合对象(转成Object)
    Iterator<?> iterator=slist.iterator();
    while (iterator.hasNext()){
    System.out.println(iterator.next());
    }
    //不允许向申明为通配符的集合类中写入对象,但是null可以
    //slist.add("AA");
    slist.add(null);
    }
    (2)泛型与继承的关系
    ? extend A:可以引用A以及子类,只可以存放null     
    ? super A:可以引用A以及父类,可以存放A以及A的子类
    (1)? extend A:只可以存放null   ? super A:可以存放A以及A的子类
    Grandfather、Father、Son三者之间的继承关系

    public class Grandfather {
    private String name;
    private Integer age;
    public Grandfather() {
    }
    }
    class Father extends Grandfather {
    public Father(){}
    }
    class Son extends Father {
    public Son(){}
    }
    测试类:
    @Test
    public void Testgenericity4(){
    List<? extends Father> list1=new ArrayList<>();//只能存放null
    //list1.add(new Grandfather());//错误
    //list1.add(new Father()); //错误
    //list1.add(new Son()) //错误
    list1.add(null);
    System.out.println(list1);

    List<? super Father> list2=new ArrayList();//可以存放Father以及Father的子类
    list2.add(new Father());
    list2.add(new Son());
    list2.add(null);
    //list2.add(new Grandfather());//错误
    System.out.println(list2);
    }
    运行结果:


    (2)? extend A:可以引用A以及子类  ? super A:可以引用A以及父类 (引用后能够添加的元素还是A以及A的子类)
    测试类:
    @Test
    public void Testgenericity2(){
    List<Grandfather> list1=new ArrayList<>();
    List<Father> list2=new ArrayList<>();
    //list1=list2; //若A是B的子类,List<A>,不是List<B>的子接口
    List<?> list=null; //通配符 ?
    list=list1;

    List<? extends Father> list3=new ArrayList<>();
    List<Son> list4=new ArrayList<>();
    list3=list4;
    list3=list2;
    //list3=list1;//错误

    List<? super Father> list5=new ArrayList();
    list5=list1;
    list5=list2;
    //list5=list4;//错误
    }
    四:补充:
     1.不可以在static方法中使用泛型的声明(类加载时,方法已加载,泛型无法确定,初始化对象时,可以确定)
    2.不可以在try-catch中使用类的泛型声明
  • 相关阅读:
    工具类
    开发中用到的工具
    项目中另外添加有用的文件:404
    如何组织项目结构:约定优于配置
    媒体查询
    响应式网站开发需要掌握的技术及国内外主流浏览器
    响应式网站概念
    sql存储过程,raisError后要return错误代码,过程最后要return 0
    delphi用TAdoStoredProc调用存储过程,兼容sql2005、2008、2014的远程事务问题
    网页视频下载牛逼工具,支持各种格式转换,比如腾讯视频格式qlv转mp4
  • 原文地址:https://www.cnblogs.com/shuaifing/p/10917270.html
Copyright © 2020-2023  润新知