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类型 ...
随机推荐
- 使用阿里云镜像maven管理配置开发环境
修改方法:在~/.m2目录下的settings.xml文件中,(如果该文件不存在,则需要从maven/conf目录下拷贝一份),找到<mirrors>标签,添加如下子标签: <mir ...
- SpringMVC handleMapping 处理器映射器 属性清单
映射器的属性清单 defaultHandler 在映射与所有处理器都不匹配的情况下,指定默认的处理器(处理器即你定义的Controller(action)类) order ...
- linux中使用Python IDE pycharm教程
今天使用vim编辑Python 并在linux中终端调试的时候,发现每次不是自己想要输出结果的时候,就要用vim编辑代码,再重新回到终端,比较浪费时间.搜索发现pycharm这一个Python ide ...
- 【转载】MySQL5.6.27 Release Note解读(innodb及复制模块)
新功能 问题描述(Bug #18871046, Bug #72811): 主要为了解决一个比较“古老”的MySQL在NUMA架构下的“swap insanity”问题,其表现为尽管为InnoDB ...
- Chris Richardson微服务翻译:重构单体服务为微服务
Chris Richardson 微服务系列翻译全7篇链接: 微服务介绍 构建微服务之使用API网关 构建微服务之微服务架构的进程通讯 微服务架构中的服务发现 微服务之事件驱动的数据管理 微服务部署 ...
- Linux架构浅谈
以下图为基础: 最内层是硬件,最外层是用户常用的应用,比如说firefox浏览器,evolution查看邮件,一个计算流体模型等等.硬件是物质基础,而应用提供服务.但在两者之间,还要经过一番周折. 还 ...
- 获取 JavaScript 异步函数返回值的笔记
wrong action function asyncfunc() { let ret = 100; setTimeout(() => { return ret; }, 1000) } let ...
- 微信小程序实现按首字母检索城市列表
不说废话,上效果图 因为我有多处要用到,所以我这里是写成自定义组件的,你也可以直接改成在page页面编写: 布局左边一个scroll-view,显示城市列表,右边一个view显示字母列表,城市列表这边 ...
- PE 001~010
题意: 001(Multiples of 3 and 5):对小于1000的被3或5整除的数字求和. 002(Even Fibonacci numbers):斐波那契数列中小于等于4 000 000的 ...
- [51nod1671]货物运输
公元2222年,l国发生了一场战争. 小Y负责领导工人运输物资. 其中有m种物资的运输方案,每种运输方案形如li,ri.表示存在一种货物从li运到ri. 这里有n个城市,第i个城市与第i+1个城市相连 ...