初学java之12 泛型编程的个人理解总结
首先,强调一个观点:
对于我这样的初学者,一定要站在虚拟机和编译器的角度来分析java 语言的种种特性,泛型也不例外。(我认为这个一条正确的学习经验)
写这篇文章起源于最近在学java,有一天在路上和一个同事在讨论什么是java泛型的时候,发现有些概念非常模糊。于是,我想澄清一下,并记录下来。
希望看过的朋友能够纠正里面的错误。非常感谢。
1 关于Java 泛型机制
在java 最初版本,
Java 泛型是通过 继承实现的,我认为 这里的继承,不是类的继承而是类型的继承.
example
public class Test
{
Object var;
Object getVar();
Void setVar( Object );
}
这是一个类.
泛型应用是这样做的
Test testObj= new =Test();
class A
{}
A a = new A();
a = (A)getVar();
因为A类 是Object类的子类,这样的话,通过类型强制转换,就可以实现赋值。
class B ,class C等等 道理一样。
通过这种方式实现和C++ 泛型一样的效果。唯一需要注意的地方在于类型转换,类型判断这些类型相关的操作需要程序员干预。
我猜测,Java 的泛型机制就是建立在类型继承这个基础上,后面版本的泛型 本质上也是这样做的
2 关于泛型的类型擦除
作为一个泛型类的开发人员,我们定义了一个泛型类,
比如
example
public class Test<T>
{
T var;
T getVar();
Void setVar( T t);
}
说明,这个的T 是一个相对于class Test 的类型参数,(可以类比: 在 void func( int x ) 中,int x是相对于method : func 的类型参数,x 是类型变量一样,)
这个泛型类在编译器中会被做一些处理而生成一个类文件。
选择原始类型(比如Object类),替代 类定义内的所有 T ,
将<T> 抹去
结果是生成的类文件效果等同于
public class Test
{
Object var;
Object getVar();
void setVar( Object t);
}
这个过程就叫做java 泛型类型擦除。
这个过程说明什么呢?
说明对于编译器而言,是不存在什么Test<String>类,Test<Date>类等等的。
对于Test<xx> 各种对象,它们都属于同一个类 Test ;
但要注意,编译器看到泛型格式<T >,编译会做一些额外的事情,比如类型转换,桥方法等等。编译器在这里把以前程序员需要手动做的事情给做。
毕竟程序员写的代码是要给编译器看懂的。通过泛型一些约定的规则,让程序员的意图为编译器所准确知道,这样写出的代码才不会有问题。
泛型类型的继承问题
首先,继承是一个类,类型之间关系的问题,所以就和对象没有关系.对象之间不存在继承的问题。
在上面的分析中,我们知道编译器不会产生具体类型参数的类。只会生成一个原始类型的普通类。即只有一个类。
那么这里又何来 泛型类型的继承问题呢?
我的理解是: 类型的继承和类的继承不是同一个概念,应该说,类型继承是类型继承,类继承也是类型继承,但类型继承就不一定是类继承
Texample : Test<String > 是 Test 的一个子类型, 并不是: Test<String > 是一个类,Test 是另一个类,Test<String > 是 Test 的子类.
在继承这个概念中,类型继承是一个超类,而类继承是一个子类。,类继承也是类型继承的一种情况,而不能说因为A类型是继承B类型,就推导出A是一个类,B是另一个类。A是B的子类。
我不知道UML里面是不是这样定义的。
初学java之12 泛型编程的个人理解总结的更多相关文章
- 初学 Java Web 开发,请远离各种框架,从 Servlet 开发
Web框架是开发者在使用某种语言编写Web应用服务端时关于架构的最佳实践.很多Web框架是从实际的Web项目抽取出来的,仅和Web的请求和响应处 理有关,形成一个基础,在开发别的应用项目的时候则可以从 ...
- Java Serializable(序列化)的理解和总结、具体实现过程(转)
原文地址:http://www.apkbus.com/forum.php?mod=viewthread&tid=13576&fromuid=3402 Java Serializable ...
- Java进阶(七)正确理解Thread Local的原理与适用场景
原创文章,始自发作者个人博客,转载请务必将下面这段话置于文章开头处(保留超链接). 本文转发自技术世界,原文链接 http://www.jasongj.com/java/threadlocal/ Th ...
- Java进阶(三十六)深入理解Java的接口和抽象类
Java进阶(三十六)深入理解Java的接口和抽象类 前言 对于面向对象编程来说,抽象是它的一大特征之一.在Java中,可以通过两种形式来体现OOP的抽象:接口和抽象类.这两者有太多相似的地方,又有太 ...
- 初学Java web(转)
转自 http://www.oschina.net/question/12_52027 OSCHINA 软件库有一个分类——Web框架,该分类中包含多种编程语言的将近500个项目. Web框架是开发者 ...
- Java基础系列1:深入理解Java数据类型
Java基础系列1:深入理解Java数据类型 当初学习计算机的时候,教科书中对程序的定义是:程序=数据结构+算法,Java基础系列第一篇就聊聊Java中的数据类型. 本篇聊Java数据类型主要包括四个 ...
- 对Java Serializable(序列化)的理解和总结
我对Java Serializable(序列化)的理解和总结 博客分类: Java技术 JavaOSSocketCC++ 1.序列化是干什么的? 简单说就是为了保存在内存中的各种对象的状 ...
- 阿里JAVA开发手册零度的思考理解(二)
转载请注明原创出处,谢谢! 说在前面 人生的大道上默默地走,就必须要有一盏灯亮着为你引导方向!而这盏灯抑或只是一句话,一句鼓励,一个赞美,一次承认,一次认可,一次相识一次交流-- 上篇文章:阿里JAV ...
- Java四种引用--《深入理解Java虚拟机》学习笔记及个人理解(四)
Java四种引用--<深入理解Java虚拟机>学习笔记及个人理解(四) 书上P65. StrongReference(强引用) 类似Object obj = new Object() 这类 ...
随机推荐
- iOS 通信常用小功能
打电话 a.最简单最直接的方式:直接跳到拨号界面 NSURL *url = [NSURL URLWithString:@"tel://10010"]; [[UIApplicatio ...
- adb 的使用
打出log:adb logcat -s fliterName ps:(fliterName就是你的tag)
- git 创建分支 并 提交到远程分支
git branch(分支命令的使用http://hbiao68.iteye.com/blog/2055493 0.可以通过git branch -r 命令查看远端库的分支情况 1,从已有的分支创建新 ...
- ASP.Net Core 里是如何把一个普通的 Action 返回类型转换为某种 IActionResult 的
秘密在于这个类型: Microsoft.AspNetCore.Mvc.Internal.ControllerActionInvoker 在它的 CreateActionResult 方法里会将相关类型 ...
- 【Gson】互相转化
Gson 是 Google 提供的用来在 Java 对象和 JSON 数据之间进行映射的 Java 类库.可以将一个 JSON 字符串转成一个 Java 对象,或者反过来. 对象转为字符串 Strin ...
- Android自定义组件
[参考的原文地址] http://blog.csdn.net/l1028386804/article/details/47101387效果图: 实现方式: 一:自定义一个含有EditText和Butt ...
- 手持移动扫描终端 PDA移动开单系统-批发零售管理
条码数据采集器通过扫描商品条码移动开单,实现便携式办公,伴随式销售,是我公司的一款最新便携式开单配套产品,采集器能通过WIFI无线局域网.GPRS互联网直接与主机连接,让公司业务人员能随时随地了解公司 ...
- Hackerrank11 LCS Returns 枚举+LCS
Given two strings, a and , b find and print the total number of ways to insert a character at any p ...
- 如何获取ResultSet的行数和列数
当我们执行数据库查询返回一个ResultSet的时候,很多情况下我们需要知道这个ResultSet的大小,即它的行数和列数.我们知道它的列数可以通过resultSet.getMetaData().ge ...
- linux 高性能服务器编程
1. 高性能定时器:时间轮,时间堆 (處理超時時間,如nginx使用紅黑樹,找出最可能超時的事件) 2. 高性能服务器程序框架:(nginx 使用的是基於事件模型,epoll,不阻塞,異步處理) 两种 ...