java里程碑之泛型--擦除和转换
在严格的泛型代码里,带泛型声明的类总应该带着泛型参数。但是为了和古老的java代码保持一致,也就是说为了向下兼容,也允许在使用带泛型声明的类时不指定实际的类型参数。如果没有为这个泛型类指定实际的参数类型,则该类型参数就被称为rawtype,也就是原始类型。比如说我们声明一个list的时候如果没有传入实际的泛型参数,我们可以抑制警告,这个时候这个警告抑制的就是rawtype,默认是声明该类型参数时指定的第一个上线类型。
- 什么是泛型的擦除?
当把一个具体泛型信息的对象赋值给另外一个没有泛型信息的变量时,所有尖括号之间的类型信息都将被扔掉。比如说将一个List<String>类型赋值给一个list,这个时候原来的这个List<String>集合的类型就变成了类型参数的上限了,也就是Object了。看一下代码:
public class Test<S>
{
S name; public S getName()
{
return name;
} public void setName(S name)
{
this.name = name;
} public static void main(String[] args) throws Exception
{
Test<Integer> test1 = new Test<>();
test1.setName(1);
Test test2 = test1;
//泛型的擦除,编译过程中丢失了具体的参数类型
Integer name2 = (Integer) test2.getName();
//运行时候对象的类型没变,擦除只是发生在编译阶段
System.out.println(test2.getName().getClass());
}
}
- 什么是泛型的转换?
从逻辑上来看,List<String>是List的子类,如果直接把一个List对象赋值给一个List<String>对象应该引起编译错误,但实际上不会。但是由于这里典型的擦除,所以我们在后面使用这个没有类型的List在做操作的时候,我们将它再次赋值给你另外一个有实际类型参数的list,这个时候很容易就会引起ClassCastException。同时这也算是给了我们一种折中的方案,就是说我们可以绕开泛型,比如我原来的是小范围的类型,那么我先将泛型移除,然后就变成了一个大范围的类型,然后我们在向下赋值,再次赋值给一个小范围的类型,编译过程都都不会报错,但是实际运行时候很容易发生类型转换异常,这也就是我们说的泛型的转换。所以我们以后还是应该养成好的习惯,每次在使用有泛型声明的类和接口时都应该传入实际的参数类型。
public class Test<S>
{
S name; public S getName()
{
return name;
} public void setName(S name)
{
this.name = name;
} public static void main(String[] args) throws Exception
{
List<Integer> list = new ArrayList<>(2);
list.add(1);
list.add(2);
List list1 = list;
List<String> list2 = list1;
System.out.println((String)list2.get(0));
}
}
java里程碑之泛型--擦除和转换的更多相关文章
- java里程碑之泛型--类型通配符
1,泛型与数组在子类上面的对比 在整理java泛型的类型通配符之前,我们先来研究下java在数组设计上的一个不合理.我们来看下面代码: public class Test { public stati ...
- java里程碑之泛型--使用泛型
现在重新整理下泛型,前面的整理好多的底层的东西理解不深.泛型很重要的,作为java的一个程碑式的改进,还是很有必要认真的理解下人家的JDK的良苦用心的. 1,什么是泛型?为什么要使用泛型? 一定要记住 ...
- java里程碑之泛型--泛型方法
前面我已经介绍过了,我们可以在定义类和接口的时候使用类型形参,在该类的方法定义中,成员变量定义中,这些类型形参都可以被当成普通类型来使用.但是如果我们在定义类和接口的时候没有使用类型形参,但是在定义方 ...
- java里程碑之泛型--泛型基本语法
1,java7提供的泛型菱形语法 在java7之前,如果使用带泛型的接口和类定义变量初始化对象的时候,构造器后面也必须带上泛型,这有点恶心的.以前我在公司一直使用的java6,所以我也已经习惯了这种写 ...
- java里程碑之泛型--深入理解泛型
所谓泛型,就是允许在定义类,接口,方法时使用类型形参,这个类型形参将在声明变量,创建对象,调用方法的时候动态的指定.JAVA5之后修改了集合中所有的接口和类,为这些接口和类都提供了泛型的支持. 关于泛 ...
- java里程碑之泛型--泛型注意的几点
1,泛型的基本语法:类名<具体类> 对象名 = new 类名<具体类>().类型参数规范如下: 1),K键,比如映射的键,key的类型 2),V值,比如Map的值,value类 ...
- JAVA 注解,泛型,反射获取泛型,并实例化
JAVA 的泛型加大了 编程的灵活性,在配合上反射,可以让我们省去大量的重复代码,当你用 SpringBoot 整合 JPA 的时候 你会发现,你的 DAO 层只需要继承 BaseDao,在显示标明泛 ...
- 关于Java泛型"擦除"的一点思考
头次写博客,想说的东西不难,关于泛型的疑问,是前一阵在学习jackson中遇到的. 下面就把我所想到的.遇到的,分享出来. 泛型是JDK1.5后的一个特性,是一个参数类型的应用,可以将这个参数声明在类 ...
- java中的伪泛型---泛型擦除(不需要手工强转类型,却可以调用强转类型的方法)
Java集合如Map.Set.List等所有集合只能存放引用类型数据,它们都是存放引用类型数据的容器,不能存放如int.long.float.double等基础类型的数据. 使用反射可以破解泛型T类型 ...
随机推荐
- 基于TCP协议的项目架构之Socket流传输的实现
项目背景 某银行的影像平台由于使用时间长,服务器等配置原因,老影像系统满足不了现在日益增长的数据量的需求,所以急需要升级改造.传统的影像平台使用的是Oracle数据库和简单的架构来存储数据(视频.图 ...
- 【线段树】BZOJ2752: [HAOI2012]高速公路(road)
2752: [HAOI2012]高速公路(road) Time Limit: 20 Sec Memory Limit: 128 MBSubmit: 1621 Solved: 627[Submit] ...
- vs2008中xlslib与libxls库的编译及使用
C++用来操作Excel的方法很多,但是涉及到跨平台,同时又要对Excel的读写操作兼顾,而且免费的库,那应该是要用xlslib和libxls了.由于技术比较菜,折腾这个折腾了一个星期了.最开始是使用 ...
- sprintf的用法
正文:printf 可能是许多程序员在开始学习C 语言时接触到的第二个函数(我猜第一个是main),说起来,自然是老朋友了,可是,你对这个老朋友了解多吗?你对它的那个孪生兄弟sprintf 了解多吗? ...
- Android App版本自动更新
App在开发过程中,随着业务场景的不断增多,功能的不断完善,早期下载App的用户便无法体验最新的功能,为了能让用户更及时的体验App最新版本,在App开发过程加入App自动更新功能便显得尤为重要.更新 ...
- Linux audio驱动模型
linux驱动 alsa模型: Linux ALSA声卡驱动之一:ALSA架构简介 Linux ALSA声卡驱动之二:声卡的创建 Linux ALSA声卡驱动之三:PCM设备的创建 Linux ALS ...
- CSS基础之盒子模型及浮动布局
盒模型 谈到盒模型,有经验的小伙伴一定滚瓜烂熟,无非就是 内容(content).填充(padding).边框(border).边界(margin): 这些属性我们可以把它转移到我们日常生活中的盒子( ...
- bzoj:1681 [Usaco2005 Mar]Checking an Alibi 不在场的证明
Description A crime has been comitted: a load of grain has been taken from the barn by one of FJ's c ...
- 2017 ACM-ICPC 亚洲区(西安赛区)网络赛 F. Trig Function(切比雪夫多项式+乘法逆元)
题目链接:哈哈哈哈哈哈 _(:з」∠)_ _(:з」∠)_ _(:з」∠)_ _(:з」∠)_ _(:з」∠)_ 哈哈哈哈哈哈,从9月16日打了这个题之后就一直在补这道题,今天终于a了,哈哈哈哈哈哈. ...
- Codeforces Round #416(Div. 2)-811A.。。。 811B.。。。 811C.dp。。。不会
CodeForces - 811A A. Vladik and Courtesy time limit per test 2 seconds memory limit per test 256 meg ...