EffectiveJava(23)为什么不能在新生代码中使用原生态类型
泛型类和泛型接口
声明一个或者多个类型参数的类或者接口.
为什么不要在新代码中使用原生态类型
原生态类型,即泛型不带参数的类型 如List的list,list就是其原生态类型
1.使用原生态类型,插入数据时,IDE会绕过编译,从将错误升级成运行时错误.而此时如果你写的代码已经离原生态类型很远,那么错误将很难调试.
如:
private final Collection stamps = ...;
stamps.add(new Coin(...));
我们知道尝试取出这个类型时才会显示错误
for(Iterator i = stamps.iterator();it.hasNext();){
//这里将会抛出一个类型转换异常(ClassCastException)
Stamp s = (Stamp)i.next();
}
使用泛型
private final Collection<Stamp> stamps = ...;
stamps.add(new Coin(...));
此时当stamps集合中添加非stamp元素时,编译器会直接报错,显示类型错误(error type)
2.从集合中删除元素时不再需要进行手工转换.编译器会为我们插入隐式的转换并确保他们不会失败.(使用泛型)
如:
for(Stamp s:stamps){
//Do something
}
//传统循环
for(Iterator<Stamp> i = stamps.iterator();i.hasNext()){
Stamp s = i.next();
//Do Something
}
移植兼容性:代码必须合法,才能将参数化的实例传递给那些被设计城市用普通类型的方法,反之亦然.
List 和 List<Object>
List将会失去安全性
public static void main(String[] args){
List<String> strings = new ArrayList<String>();
unsafeAdd(strings,new Integer(42));
String s = string.get(0);
}
private static void unsafeAdd(List list,Object o){
list.add(o);
}
它可以被编译,但是会因为使用原生态类型收到一条警告.如果换成
private static void unsafeAdd(List<Object> list,Object o){
list.add(o);
}
将无法通过编译
3.即使你不确定或不在乎集合元素类型,也要使用无限制的通配符类型来充当泛型的参数类型
static int numElementsInCommon(Set s1,Set s2){
int result = 0;
for(Object o1:s1){
if(s2.contains(01))
result++;
}
return result;
}
----->>>>
static int numElementsInCommon(Set<?> s1,Set<?> s2){
你可以将任何元素插入到原生态类型中,但你不能把除了null以外的任何元素放入set<?>中,否则将会报错
那我们在何时可以使用原生态类型呢?如果不能被使用,那java为什么不移除它?
确实有两种特殊情况使用原生态类型的例子
a.在类文字中必须使用原生态类型.规范不允许使用参数化类型.
如:List
if(o instanceof Set){
//受检转换
Set<?> m = (Set<?>)o;
}
总结:使用原生态类型会在运行时导致异常,因此不要在新代码中使用.原生态类型只是为了引入泛型之前遗留代码进行兼容和互用而提供的.
Set 是个参数化类型,表示可以包含任何对象类型的一个集合 safe
Set
EffectiveJava(23)为什么不能在新生代码中使用原生态类型的更多相关文章
- EffectiveJava——请不要在代码中使用原生态类型
先看一个栗子,看看能不能找出来里面的错误: /** * 请不要在新代码中使用原生态类型 * @author weishiyao * */ public class Test { public stat ...
- effective_java第23条:请不要新代码中使用原生态类型
从这条开始涉及泛型相关的点. 从JDK5开始Java新增了“泛型”新特性,例如:List<String>,在这之前则只有List不会限定类型. 如今的JDK版本中还是可以写原生类型,但这会 ...
- Dynamics AX 2012 R2 从代码中调用SSRS Report
平时,我们制作SSRS Report的方法主要有两种:使用Query或RDP.如果需要为报表传递参数,就要在代码中为报表参数赋值,然后在代码中调用报表.下面我总结下这两种报表在代码中传参和调用的方式: ...
- 在Visual Studio代码中使用Flask
Flask是一个用于Web应用程序的轻量级Python框架,它提供了URL路由和页面呈现的基础知识. Flask被称为“微”框架,因为它不直接提供表单验证,数据库抽象,身份验证等功能.这些功能由称为F ...
- EffectiveJava(28)怎么利用有限制的通配符类型来提升API的灵活性
有时候,我们需要的灵活性要比不可变类型所能提供的更多.所以针对一些通用性的方法,通常用泛型代替固定的数据类型,特别是当你要将某个方法打包成Jar的时候. 结合之前的例子,我们增加尝试用有限制的通配符类 ...
- 「Flink」Flink中的时间类型
Flink中的时间类型和窗口是非常重要概念,是学习Flink必须要掌握的两个知识点. Flink中的时间类型 时间类型介绍 Flink流式处理中支持不同类型的时间.分为以下几种: 处理时间 Flink ...
- C语言初学者代码中的常见错误与瑕疵(23)
见:C语言初学者代码中的常见错误与瑕疵(23)
- 一个超复杂的间接递归——C语言初学者代码中的常见错误与瑕疵(6)
问题: 问题出处见 C语言初学者代码中的常见错误与瑕疵(5) . 在该文的最后,曾提到完成的代码还有进一步改进的余地.本文完成了这个改进.所以本文讨论的并不是初学者代码中的常见错误与瑕疵,而是对我自己 ...
- C语言初学者代码中的常见错误与瑕疵(5)
问题: 素数 在世博园某信息通信馆中,游客可利用手机等终端参与互动小游戏,与虚拟人物Kr. Kong 进行猜数比赛. 当屏幕出现一个整数X时,若你能比Kr. Kong更快的发出最接近它的素数答案,你将 ...
随机推荐
- springmvc JSR303 Validate 注解式,校验数据
参考:http://www.cnblogs.com/liukemng/category/578644.html 先进行配置: <!-- 默认的注解映射的支持 --> <mvc:ann ...
- golang命令行参数解析
package main import ( "fmt" "os" ) func main(){ s:= os.Args fmt.Println(s) } 直接执 ...
- Selenium2+python自动化74-jquery定位【转载】
转至博客:上海-悠悠 前言 元素定位可以说是学自动化的小伙伴遇到的一道门槛,学会了定位也就打通了任督二脉,前面分享过selenium的18般武艺,再加上五种js的定位大法. 这些还不够的话,今天再分享 ...
- Appium+python自动化28-name定位【转载】
本篇转自博客:上海-悠悠 前言 appium1.5以下老的版本是可以通过name定位的,新版本从1.5以后都不支持name定位了 一. name定位报错 1.最新版appium V1.7用name定位 ...
- 执行程序(例如UltraEdit)在WIN7下添加到右键菜单
把下面提供的代码复制到记事本,保存为注册表文件(*.reg),右键合并即可.注意把最后一行换成你自己的路径. Windows Registry Editor Version 5.00 [HKEY_CL ...
- 微信token
<?php define("TOKEN", "lmaster"); function checkSignature() { //从GET参数中读取三个字段 ...
- CentOS 7 下nagios搭建记录
跟随 园子的文章搭建 http://www.cnblogs.com/mchina/archive/2013/02/20/2883404.html 1.遇 nagios插件地址迁移错误,记录解决. 2. ...
- 设计模式-设计原则(Design Principle)
本文由@呆代待殆原创,转载请注明出处. 写在前面:所谓设计原则并不是一定要遵守的法则,只是一种建议,因为保持这些原则本身会有一定代价,若是这些代价超过了带来的好处就得不偿失了,所以一切还是以简单为准. ...
- 【枚举】【二分答案】【分块答案】【BFS】【最大流】【Dinic】bzoj1189 [HNOI2007]紧急疏散evacuate
[法一]枚举Time(0~N*M): S->'.'(1); 'D'->T(Time); '.'->'D'(dis(用BFS预处理,注意一旦到达'D',BFS就不能继续扩展了,注意di ...
- C#中函数库方式重复播放MP3音乐
public void play() { this.TemStr = ""; this.TemStr = this.TemStr.PadLeft(0x7f, Convert.ToC ...