java里程碑之泛型--深入理解泛型
所谓泛型,就是允许在定义类,接口,方法时使用类型形参,这个类型形参将在声明变量,创建对象,调用方法的时候动态的指定。JAVA5之后修改了集合中所有的接口和类,为这些接口和类都提供了泛型的支持。
关于泛型的底层,我们先来看看一段代码:
public class Test
{
public static void main(String[] args)
{
List<String> strList = Lists.newArrayList();
List<Integer> intList = Lists.newArrayList();
System.out.println(strList.getClass() == intList.getClass());
}
}
上面的代码new了2个list,然后判断这2个list的类是不是同一个?如果没有深入的了解过泛型,我们很容易以为上面的代码输出是false,但是运行上面的代码,实际输出是true。为什么呢?因为不管泛型的实际类型是什么,他们在运行时总是同样的类。比如下面的代码:
public class Test<T>
{
public static void main(String[] args)
{
Test<String> test = new Test<>();
List<String> strList = Lists.newArrayList();
List<Integer> intList = Lists.newArrayList();
System.out.println(strList.getClass() == intList.getClass());
}
}
我们在编译之后,用反编译打开jar包看一下,代码的源码如下:
public class Test<T>
{
public static void main(String[] args)
{
Test test = new Test();
List strList = Lists.newArrayList();
List intList = Lists.newArrayList();
System.out.println(strList.getClass() == intList.getClass());
}
}
从上面的2段代码我们得出一个结论,不管为泛型的类型形参传入哪一种类型实参,对于java来说,他们都被当成了同一个类来处理,在内存中也使用同一块内存空间。所以这里有2个注意的地方;
1),在静态方法,静态初始化块,静态变量的声明和初始化中都不允许使用类型形参。具体看下面的代码演示:
public class Test<T>
{
//实例属性,实例方法是可以的,具体的T就是初始化这个类时候传入的形参。以下代码正常
T name;
public void test(T id)
{ }
//静态属性和静态方法不可以用,这个时候没有实例初始化,也就是说这个T很有可能还没有传入。以下代码出错
static T id;
public static void test(T id)
{ }
}
2),在系统中并不会生成泛型类,所以instanceof运算符后不能使用泛型类。具体看下面的代码演示:
public class Test<T>
{
public void test()
{
Collection<String> list = Lists.newArrayList();
//下面代码正常
if (list instanceof ArrayList)
{ }
//下面代码报错,instanceof运算符后不能使用泛型
if (list instanceof ArrayList<String>)
{ }
}
}
总结:我们在使用泛型的时候,虽然程序只定义了一个List<E>的接口,但是在实际使用过程中我们可以传入随便的E的类型,这样子就可以产生无数多个List接口,只要为E传入不同的类型实参,系统就会多出一个新的List子接口。特别要注意的是,上面的任何一个子接口都不能被替换成一个固定的接口,比如List<String>不会替换成ListString,系统没有进行源代码复制,二级制代码中没有,磁盘和内存中都没有,也就是说这种子类我们只是可以这样子理解,但是在物理上根本不存在。
java里程碑之泛型--深入理解泛型的更多相关文章
- Java泛型深入理解
泛型的优点: 泛型的主要优点就是让编译器保留參数的类型信息,执行类型检查,执行类型转换(casting)操作,编译器保证了这些类型转换(casting)的绝对无误. /******* 不使用泛型类型 ...
- Java基础 -- 深入理解泛型
一般的类和方法,只能使用具体的类型:要么是基本类型,要么是自定义的类.如果要编写可以应用于多种类型的代码,这种刻板的限制对代码的束缚就会很大. 而泛型很好的解决了这个问题,这也是Java SE5的重大 ...
- java泛型的理解
总体介绍泛型: 1.泛型是计算机程序中一种重要的思维方式,它将数据结构和算法与数据类型相分离,使得同一套数据结构和算法,能够应用于各种数据类型,而且还可以保证类型安全,提高可读性.在Java中,泛型广 ...
- Java泛型深入理解(转载)
原文地址 http://blog.csdn.net/sunxianghuang/article/details/51982979 泛型之前 在面向对象编程语言中,多态算是一种泛化机制.例如,你可以将 ...
- 你对Java泛型的理解够深入吗?
泛型 泛型提供了一种将集合类型传达给编译器的方法,一旦编译器知道了集合元素的类型,编译器就可以对其类型进行检查,做类型约束. 在没有泛型之前: /** * 迭代 Collection ,注意 Coll ...
- 重读《深入理解Java虚拟机》六、Java泛型 VS C#泛型 (伪泛型 VS 真泛型)
一.泛型的本质 泛型是参数化类型的应用,操作的数据类型不限定于特定类型,可以根据实际需要设置不同的数据类型,以实现代码复用. 二.Java泛型 Java 泛型是Java1.5新增的特性,JVM并不支持 ...
- 关于Java泛型深入理解小总结
1.何为泛型 首先泛型的本质便是类型参数化,通俗的说就是用一个变量来表示类型,这个类型可以是String,Integer等等不确定,表明可接受的类型,原理类似如下代码 int pattern; //声 ...
- 通过Java反射来理解泛型的本质
集合框架中经常会使用泛型指定集合中所存放元素的类型,保证集合的统一性,从集合中取出元素的时候也避免了类型强制转换的操作,所以我们使用常规的方式来往集合中存放元素的时候,如果指定泛型,那么我们只能向集合 ...
- 《徐徐道来话Java》(2):泛型和数组,以及Java是如何实现泛型的
数组和泛型容器有什么区别 要区分数组和泛型容器的功能,这里先要理解三个概念:协变性(covariance).逆变性(contravariance)和无关性(invariant). 若类A是类B的子类, ...
随机推荐
- 云服务器 远程mysql 无法连接
问题:mysql不管是用免安装版的,还是用直接安装的,还是用phpStudy直接发布的mysql服务.都只能用localhost登录,不能用服务器的ip进行远程访问 遇到这个问题.按照网上大家介绍的方 ...
- IdentityServer Topics(5)- 使用第三方登录
ASP.NET Core有一个灵活的方式来处理外部认证. 这包括几个步骤. 如果您使用的是ASP.NET Identity,则许多底层技术细节对您而言都是隐藏的. 建议您还阅读Microsoft文档并 ...
- linux基础命令学习总结
本附录([美]哈恩:<Unix&Linux大学教程>附录B,张杰良译,清华大学出版社,2010年)摘要描述了书中所涉及的143个Unix使命,并且按照命令的类别进行排列.在每个名称 ...
- 学习笔记-express路径问题
在页面渲染成功之后,报错出现静态文件css样式引用路径出错,于是我就根据express api文档,托管静态文件作出修改,最后全是徒劳.于是我又从引用开始找起,<link rel="s ...
- DOCKER 开发学习记录
DOCKER常用命令及参数 DOCKER镜像管理命令: 检索:docker search image_name 下载:docker pull image_namge 查看本地镜像:docker ima ...
- hackerrank DFS Edges
瞬间移动 题意:要求构造一个图,使其dfs树中有t条树边,b条返祖边,f条前向边,c条其他边. 膜了题解才会,好神啊. 考虑所有结点的深度之和,这个值必须介于$[max(b,f+t),C^{2}_{n ...
- Codeforces 833D Red-black Cobweb【树分治】
D. Red-black Cobweb time limit per test:6 seconds memory limit per test:256 megabytes input:standard ...
- CodeForces 543D:Road Improvement
题目:http://codeforces.com/problemset/problem/543/D 题意:给你一棵树,一开始边都是0,可以使任意的边变成1,对于每一个根节点求使得它到其他任一点的路径上 ...
- 数塔~~dp学习_1
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2084 数塔 Time Limit: 1000/1000 MS (Java/Others) Mem ...
- linux命令 uname -r 和 uname -a 的解释与演示
1.uname -r : 显示操作系统的发行版号2.uname -a :显示系统名.节点名称.操作系统的发行版号.内核版本等等. 系统名:Linux 节点名称: iZ2zeeailqvwws5dcui ...