EffectiveJava(25)泛型和数组的使用取舍及规范
2024-08-26 04:38:09
泛型和数组
泛型:1.泛型是不可变的.对于任意两个不同类型Type1,type2;List既不是List的子类型,也不是List的超类型
2.泛型是通过擦除来实现的.故泛型只在编译时强化它们的信息,并在运行时丢弃(擦除)他们的元素类型信息
2.a:擦除:使泛型可以与没有使用泛型的代码随意进行互用
数组:1.数组是协变的.如果Sub为Super的子类型,那么Sub[]就是Super[]的子类型
2.数组是具体化的,这表明数组会在运行时才知道并检查他们的元素类型约束
因此,泛型和数组不能很好的进行结合使用,创建泛型数组是非法的,因为他违背了泛型系统提供的基本保证.但后面我们会给出这条的解决方案.
//cannot create a generic array of List<String>
//ClassCastException
List<String>[] stringLists = new List<String>[1];
/List<Integer> initList = Arrays.asList(42);
将List<String>数组保存到一个Object数组变量中,由于数组的协变性,合法
//Object[] objects = stringLists;
//将List<String>保存到Object数组里唯一的元素中,因为泛型是通过擦除实现的,合法 --List<String>运行时是List
objects[0] = initList;
String str = stringList[0].get(0);
当你得到泛型数组创建错误时,最好的解决办法通常是优先使用集合类型List,而不是数组类型E[].这样可能会损失一些性能或者简洁性,但是有更高的类型安全性和互用性
如:
//没有泛型时的代码
static Object reduce(List list,Function f,Object initVal){
synchronized(list){
Object result = initVal;
for(Object o:list)
result = f.apply(result,o);
}
}
inteface Function(){
Object apply(Object arg1,Object arg2);
}
//利用List的toArray方法在持有锁的时候修改reduce方法来复制列表中的内容,也可以备份减法
static Object reduce(List list,Function f,Object initVal){
Object[] snapshot = list.toArray();
Object result = initVal;
for(E e:snapshot){
result = f.apply(result,e);
}
return result;
}
//如果使用泛型定义接口,那么就需要用列表代替数组
inteface Function<T>(){
T apply(T arg1,T arg2);
}
----->>>>修改过后的static
static <E> E reduce(List<E> list,Function<E> f,E initVal){
List<E> snapshot;
synchronized(list){
snapshot = new ArrayList<E>(list);
}
E result = initVal;
for(E e:snapshot){
result = f.apply(result,e);
}
return result;
}
虽然这个版本代码比较冗长,但是可以确保不会产生ClassCastException
总结:数组和泛型有着非常不同的类型规则.数组是协变且可以具体化的;泛型是不可变且可以被擦除的.因此,数组提供了运行时的类型安全,但是没有编译时的类型安安全,反之,对于泛型也一样.一般来说,数组和反省不能很好地混合使用.如果你发现自己将它们混合使用,并且得到了编译时错误或警告,那么就应该用列表代替数组!
最新文章
- ASP.NET Core 中文文档 第四章 MVC(3.3)布局视图
- P1220 关路灯
- gulp基本用法
- 三、jQuery--jQuery实践--瀑布流布局
- 微信客户端自带的Js Api:WeixinJSBridge
- ACM: A Simple Problem with Integers 解题报告-线段树
- 转:使用vs2013打开VS2015的工程文件的解决方案(适用于大多数vs低版本打开高版本)
- NSJSONSerialization介绍
- 剑指offer系列43---判断平衡二叉树
- Python深复制浅复制or深拷贝浅拷贝
- G - Island Transport - hdu 4280(最大流)
- CSS 实现底部固定
- 如何用正确的姿势查看 主机系统的CPU信息
- 十分钟帮你搭建专业的内容付费平台(APP/网站)
- html-webpack-plugin的使用
- P2045 方格取数加强版
- aliyun centos7 挂载云盘
- Android的Databinding-单向绑定
- Domain Driven Development相关概念
- SQL SERVER 2008R2 安装问题
热门文章
- 【C++】隐式类型转换和 explicit关键字
- dict的setdefault(学习bottle源代码)
- Laravel项目使用腾讯云对象存储上传图片(cos-php-sdk-v5版本)
- hdu5076
- 最快的序列化组件protobuf的.net版本protobuf.net
- Luis创建与发布
- paramiko 使用总结(SSH 操作远端机器)
- 机器人搬重物(BFS)
- 【最近公共祖先】【树链剖分】CODEVS 1036 商务旅行
- 【欧拉函数】BZOJ2190-[SDOI2012]longge的数学问题