• 再回首Java第二十七天


    泛型与数组

    JDK1.5还有一个很重要的设计原则:如果一段代码在编译时系统没有产生:”unchecked未经检测的转换“,则程序在运行时不会引发”ClassCastException“异常。正是基于这个原因,所以数组元素的类型不能包含类型变量或类型形参,除非是无上限的类型通配符。但可以声明这样的数组,即使声明元素类型包含类型变量或类型形参的数组。也就是说:只能声明List<String>[]数组,但不能创建ArrayList<String>[10]这样的数组对象

    假设Java能支持创建ArrayList<String>[10]这样的数组对象,则有如下程序

     //下面代码实际上是不允许的

    List<String>[]  lsa=new ArrayList<String>[10];

    //强制类型转化为一个Object数组

    Object[] oa=(Object[])lsa;

    List<Integer> li=new ArrayList<Integer>();

    li.add(new Integer(3));

    //将List<Integer>对象作为oa的第一个元素

    //下面代码没有任何警告

    oa[1]=li;

    //下面代码也不会有任何警告,但是会引起ClassCastException异常

    String s=lsa[1].get(0);

    如果能够创建ArrayList<String>[10]这样的数组,经过中间系列的程序运行,势必在代码最后一行引起异常,这就违背Java泛型的设计原则

    如果将程序该成如下形式

    //下面代码编译时有 “[unchecked]未经检查的转换”警告

    List<String>[] lsa=new ArrayList[10];

    Object[] oa=(Object[]) lsa;

    List<Integer> li=new ArrayList<Integer>();

    li.add(new Integer(3));

    oa[1]=li;

    //下面代码将一起ClassCastException异常

    String s=lsa[1].get(0);

    上面代码:声明List<String>[]类型的数组变量时允许的;但不允许创建List<String>[]类型的对象,所以创建了一个ArrayList[10]的数组对象,这是允许的。只是把ArrayList<10>对象赋值给List<String>[]变量时会有编译警告:未经检查的转换,即编译器不保证这段代码的类型安全的。所以后面代码会引发ClassCastException异常,但因为编译器 已经提出了警告,所以完全有可能发生这种异常

    Java运行创建无上限的通配符泛型数组,例如new ArrayList<?>[10],在这种情况下程序不得不进行强制类型转换,如下代码所示

    List<?>[] lsa=new ArrayList<?>[10];

    Object[] oa=(Object[]) lsa;

    List<Integer> li=new ArrayList<Integer>();

    li.add(new Integer(3));

    oa[1]=li;

    //下面代码将一起ClassCastException异常

    String s=lsa[1].get(0);

    编译上面代码不会引起任何警告,当程序运行到最后引发ClassCastException异常,因为程序将lsa的第一个元素的第一个集合元素赋值给String类型的变量,所以程序应该自己通过instanceof运算符来保证它的数据类型

    List<?>[] lsa=new ArrayList<?>[10];

    Object[] oa=(Object[]) lsa;

    List<Integer> li=new ArrayList<Integer>();

    li.add(new Integer(3));

    oa[1]=li;

    Object target=lsa[1].get(0);

    if(target instanceof String){

    String s=(String)target;

    }

    与此类似的是:创建元素类型是类型变量的数组对象也将导致编译错误。如下面代码所示:

    <T> T[] makeArray(Collection<T> coll){

    //下面代码将导致编译错误

    return new T[coll.size()];

    }

    因为类型变量在运行时并不存在,所以编译器无法确定实际类型是什么

  • 相关阅读:
    php array_flip() 删除数组重复元素——大彻大悟
    深入理解HTTP协议之POST方法——ajax实例
    RHEL/CentOS/Fedora各种源(EPEL、Remi、RPMForge、RPMFusion)配置
    SpringMVC注解校验
    Mybatis源码解析(二)
    MyBatist庖丁解牛(三)
    MyBatist庖丁解牛(二)
    linux模拟http请求命令
    清空文件内容
    git上如何删除已有项目
  • 原文地址:https://www.cnblogs.com/Mrxiaolong/p/5496721.html
Copyright © 2020-2023  润新知