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类型 ...
随机推荐
- 基于 socket.io 的 AI 服务 杂谈
为什么会想到来聊下这个话题. 前几天在公司的项目中,开发一个基于 socket.io 的直播 IM 功能. 直播分为两部分,一部分是比较昂贵的 视频推流, 另外一部分是 IM 即时聊天服务. 从这里开 ...
- Java学习笔记2(输入与随机数简单介绍)
输入: import java.util.Scanner; public class ScannerDemo{ public static void main(String[ ] args){ Sca ...
- Windows程序设计学习笔记(一)Windows内存管理初步
学习Windows程序设计也有一些时间了,为了记录自己的学习成果,以便以后查看,我希望自己能够坚持写下一系列的学习心得,对自己学习的内容进行总结,同时与大家交流.因为刚学习所以可能有的地方写不不正确, ...
- BaseServer的介绍
服务器类型 5种类型:BaseServer,TCPServer,UnixStreamServer,UDPServer,UnixDatagramServer.注意:BaseServer不直接对外服务. ...
- 多个tab选项卡
<!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title> ...
- HTML基础知识(常见元素、列表、链接元素、图片元素)
1.HTML有关概念 全称: Hyper Text Markup Language(超文本标记语言) 其文件扩展名为".html"或".htm" * 超文本 - ...
- (亲测)1分钟破解IDM权限,傻瓜都能学会的破解方法(番外篇:利用破解工具直接破解IDM)
Internet Download Manager (IDM)是比较好用的一款下载工具~ 上一节我讲到一种利用修改防火墙来进行阻止访问服务器,请参看这篇文章(亲测)躺着破解IDM下载权限,治疗不用破解 ...
- stl总结精简版
STL 精简版 vetor #include<vector> #include<cstdio> #include<algorithm> #include<io ...
- hdu_1006 Tick and Tick(暴力模拟)
hdu1006 标签(空格分隔): 暴力枚举 好久没有打题了,退队了有好几个月了,从心底不依赖那个人了,原来以为的爱情戏原来都只是我的独角戏.之前的我有时候好希望有个人出现,告诉自己去哪里,做什么,哪 ...
- java与C++变量初始化的对比
java尽力保证:所有变量在使用前都能得到恰当的初始化 ①函数/方法局部变量的初始化 在C/C++中,变量的初始化还是得依赖于程序员的自觉性.对于函数局部变量,编译器不会为基本类型赋予默认初始值,新手 ...