首页 > 编程语言 >Java泛型与数组

Java泛型与数组

时间:2022-11-19 17:01:16浏览次数:54  
标签:Java lsa 代码 List li 数组 泛型 new ArrayList

Java泛型与数组

1.* 泛型与数组

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

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

点击查看代码
//下面代码实际上是不允许的
List<String>[] lsa = new List<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);

在上面代码中,如果List<String>[] lsa = new List<String>[10]代码是合法的,经过中间系列的程序运行,势必在String s = lsa[1].get(0)处引发运行时异常,这就违背了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>[] lsa = new ArrayList[10]声明了List<String>[]类型的数组变量,这是允许的;但不允许创建List<String>[]类型的对象,所以创建了一个类型为ArrayList[10]的数组对象,这也是允许的。只是把ArrayList[10]对象赋给List<String>[]变量时会有编译警告[unchecked]未经检查的转换,即编译器并不保证这段代码是类型安全的。上面代码同样会在String s = lsa[1].get(0)处引发运行时异常,但因为编译器已经提出了警告,所以完全可能出现这种异常。

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 = (String)lsa[1].get(0);

编译上面代码不会发出任何警告,运行上面程序将在String s = (String)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()];
}

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

标签:Java,lsa,代码,List,li,数组,泛型,new,ArrayList
From: https://www.cnblogs.com/hzhiping/p/16906448.html

相关文章

  • java——集合——Set集合——Set集合的概述&HashSet集合介绍
                    Set集合的概述java.util.Set接口和java.util.List接口一样,同样继承自Collection接口,它与Collection接口中的方法......
  • Java泛型擦除与转换
    Java泛型擦除与转换1.*擦除与转换在严格的泛型代码里,带泛型声明的类总应该带着类型参数。但为了与老的Java代码保持一致,也允许在使用带泛型声明的类时不指定实际的类型......
  • java——集合——Set集合——哈希值
    哈希值哈希值:是一个十进制的整数,由系统随机给出(就是对象的地址值,是一个逻辑地址,是模拟出来得到地址,不是数据实际存储的物理地址)在Object类有一个方法,可以获取对......
  • java——集合——List集合——ArrayList集合
                                                  ArrayList集合Arr......
  • java——集合——List集合——LinkedList集合
    LinkedList集合java.util.LinkedList集合implementsList接口##**LinkedList集合的特点:**1.底层是一个链表结构:查询慢,增删快2.里边包含了大量操作首尾元素的方法注......
  • Java——集合——数据结构——栈、队列、数组、链表、红黑树
                                                      ......
  • JAVA仓库管理系统(附源码+调试)
    JAVA仓库管理系统——三只松鼠仓库管理系统功能描述(1)登录模块:登录信息等存储在数据库中(2)基本档案管理模块:供货商管理,销售商管理,货品档案管理,仓库管理(3)采购订货模块:用户可以......
  • 【JAVA】线程
    线程概念线程:程序进程:运行中的程序线程由进程创建,是进程的实体。一个进程可以有多个线程。单线程,多线程并发:同一时刻多个任务交替进行。单核cpu并行:同一时刻多个任......
  • go对数组对象排序
    1.根据时间对数组对象排序packagemainimport(  "fmt"  "time"  "github.com/ahmetb/go-linq/v3")typeCustomTimetime.Timefunc(aCustomTime)......
  • 【Java】 Springboot+Vue 大文件断点续传
     同事在重构老系统的项目时用到了这种大文件上传 第一篇文章是简书的这个:https://www.jianshu.com/p/b59d7dee15a6 是夏大佬写的vue-uploader组件:https://www......