EffectiveJava(25)泛型和数组的使用取舍及规范
泛型和数组
泛型: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
总结:数组和泛型有着非常不同的类型规则.数组是协变且可以具体化的;泛型是不可变且可以被擦除的.因此,数组提供了运行时的类型安全,但是没有编译时的类型安安全,反之,对于泛型也一样.一般来说,数组和反省不能很好地混合使用.如果你发现自己将它们混合使用,并且得到了编译时错误或警告,那么就应该用列表代替数组!
EffectiveJava(25)泛型和数组的使用取舍及规范的更多相关文章
- 重学《C#高级编程》(泛型与数组)
前段时间工作比较忙,就没有写随笔了,现在继续. 前两天重新看了泛型和数组两章,简单说下我自己的收获吧 泛型 我们知道数组是一种批量的数据格式,而泛型其实就是一种自定义的批量数据格式,当数组和C#现有的 ...
- Delphi泛型动态数组的扩展--转贴
此文章转载于http://www.raysoftware.cn/?p=278&tdsourcetag=s_pcqq_aiomsg的博客 从Delphi支持泛型的第一天起就有了一种新的动态数组类 ...
- Java 泛型 五:泛型与数组
简介 上一篇文章介绍了泛型的基本用法以及类型擦除的问题,现在来看看泛型和数组的关系.数组相比于Java 类库中的容器类是比较特殊的,主要体现在三个方面: 数组创建后大小便固定,但效率更高 数组能追踪它 ...
- Java泛型与数组深入研究
Java中的泛型与数组平时开发用的很多,除了偶尔遇到"NullPointerException"和"IndexOutOfBoundsException"一般也不 ...
- 《徐徐道来话Java》(2):泛型和数组,以及Java是如何实现泛型的
数组和泛型容器有什么区别 要区分数组和泛型容器的功能,这里先要理解三个概念:协变性(covariance).逆变性(contravariance)和无关性(invariant). 若类A是类B的子类, ...
- 25个JavaScript数组方法代码示例
摘要: 通过代码掌握数组方法. 原文:通过实现25个数组方法来理解及高效使用数组方法(长文,建议收藏) 译者:前端小智 Fundebug经授权转载,版权归原作者所有. 要在给定数组上使用方法,只需要通 ...
- PAT 甲级 1052 Linked List Sorting (25 分)(数组模拟链表,没注意到不一定所有节点都在链表里)
1052 Linked List Sorting (25 分) A linked list consists of a series of structures, which are not ne ...
- C#学习笔记二 (资源托管,泛型,数组和元组,运算符和类型强制转换)
托管和非托管资源 1.托管资源是指GC管理的内存空间,非托管资源是指文件句柄,网络连接,数据库连接等. 2.方法中临时申请的变量,被存放在栈中.栈存储非对象成员的值数据.例如在方法中有B b=new ...
- C#中的泛型 / 泛型类 / 数组、ArrayList和List三者的区别
在C#中数组,ArrayList,List都能够存储一组对象,那么这三者到底有什么样的区别呢. 数组 数组在C#中最早出现的.在内存中是连续存储的,所以它的索引速度非常快,而且赋值与修改元素也很简单. ...
随机推荐
- 用java实现word转html
由于项目需要,要完成将上传的word文件转成html文件的功能.在网上搜了一下,大致有3种方法:1.用jacob实现 2.用poi实现 3.用openoffice实现. 从网上来看好像jacob用的人 ...
- Xcode升级到7之后 发现速度超级慢
Xcode升级到7之后 发现速度超级慢 转自:http://www.jianshu.com/p/608803eb1e12 解决方法,慢google了一下是由于插件造成饿,于是乎将Alcatraz安装的 ...
- python之多并发socket(zz)
本文转载自:http://www.cnblogs.com/bainianminguo/p/7337210.html 先看socket多并发的服务端的代码,这里是用多线程实现的多并发socketserv ...
- 关系和非关系型数据库区别(以及oracle和mysql的区别)
一.关系型数据库 关系型数据库,是指采用了关系模型来组织数据的数据库. 关系模型是在1970年由IBM的研究员E.F.Codd博士首先提出的,在之后的几十年中,关系模型的概念得到了充分的发展并逐 ...
- head first (二):观察者模式
首先推荐一下别人写的,很不错可以参考,http://www.cnblogs.com/li-peng/archive/2013/02/04/2892116.html 1.定义 观察者模式:在对象之间定义 ...
- 转载] magento 产品数据表结构
原文地址:http://blog.sina.com.cn/s/blog_9302097a010120l4.html 数据库-- 产品数据库表结构分析 product 1数据库实体表:catalog_p ...
- shell脚本学习(二)
shell传递参数 shell脚本在执行是可以传递参数,脚本内获取参数的格式为:$n,n为一个数字,1为第一个参数,2为第二个参数,以此类推 其中,$0代表了要执行的文件名 实例: 代码如下: #!/ ...
- ACM竞赛常用头文件模板-备忘
备忘. #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> ...
- HDU 1532.Drainage Ditches-网络流最大流
Drainage Ditches Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- AMQ学习笔记 - 04. 消息选择器
概述 消息选择器使用类似于SQL语法,为Consumer指定基于Message属性的筛选条件. 消息选择器 发送的时候,给消息添加一些属性:在接收的时候,根据属性进行过滤. API javax.jms ...