zoukankan      html  css  js  c++  java
  • 再回首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()];

    }

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

  • 相关阅读:
    Asp.net2.0 中自定义过滤器对Response内容进行处理 dodo
    自动化测试工具 dodo
    TestDriven.NET 2.0——单元测试的好助手(转) dodo
    JS弹出窗口的运用与技巧 dodo
    ElasticSearch 简介 规格严格
    修改PostgreSQL字段长度导致cached plan must not change result type错误 规格严格
    Linux系统更改时区(转) 规格严格
    mvn编译“Cannot find matching toolchain definitions for the following toolchain types“报错解决方法 规格严格
    ElasticSearch 集群 & 数据备份 & 优化 规格严格
    Elasticsearch黑鸟教程22:索引模板的详细介绍 规格严格
  • 原文地址:https://www.cnblogs.com/Mrxiaolong/p/5496721.html
Copyright © 2011-2022 走看看