最近看Spring 源代码的时候遇到了一个关于泛型的问题,于是就请教我的老大帮我
解释了一下,然后又自己看了一点资料,感觉对泛型已经有了一定的理解了,就先
把这些想法记录下来,供有需要的人参考同时也为了能够加深理解
如果你在看JDK1.5的源码的时候就会发现,java.util.HashMap这个类里面出现了
这种代码:
<!---->
public class HashMap<K,V>
extends AbstractMap<K,V>
implements Map<K,V>, Cloneable, Serializable
{
public HashMap(Map<? extends K, ? extends V> m) {.}
}
里面出现了大量的角号和K,V,T...等不明所以的代码,其实这就是泛型的应用。
泛型的一些概念:
List<E> , List< String > , List
List<E>是参数话类型 parameterized type ,
E是(formal)类型参数 type parameter,
String 实际类型参数 actual type argument,
List是自然类型 raw type
为什么会出现泛型:
原来的JDK中
当我不知道user到底是个什么对象的时候只能这样写:
static Object maskNull(Object o){
return key == null ? NULL_KEY :key;
}
如果我在外面使用的时候:
User u = ...;
User user = (User)map.maskNull(u);
这里用到了向上转型,把map.maskNull(u)的返回对象强制转型为了User,强制转为什么类型完全有程序员控制,所以我在这里这样写也是可以的
Department d = (Department)map.maskNull(u);
这个错误在编译的时候是不会有任何错误提示的,必须到了runtime才能知道返回的类型和Department是不匹配的
但是如果使用了泛型以后我可以写成这样
static <T> T maskNull(T key) {
return key == null ? (T)NULL_KEY : key;
}
User u = ...;
User user = map.maskNull(u);
当我再写成Department d = map.maskNull(u);
的时候就会编译失败,因为方法要求参数和返回值必须是 T 类型的,当然这里的T只是暂时的一个声明,类似于去占一个坑,当我需要是User类型的时候,我就用 User去替换掉它,这样编译的时候就要求传进的和返回的必须是一致的类型,所以我们刚才的那种写法就不行了,这样编译器就使用自身的机制保证类型安全type-safe
但是泛型还存在另外一个重要的概念bridge method
先讲一下JDK对泛型的支持:上面的讲解虽然说泛型很有用,但是泛型在runtime是没有任何作用的,只是为了编译期的方便,所以当过了编译期之后还是要转换为普通代码的执行方式的,也就是说过了编译期,带角号的部分会被抹掉,变成了原始的方式
static Object maskNull(Object o){...}
那么现在看下面的代码:
class A<T>{
T setX(T t){...}
}
class B extends A<String>{
String setX(String s){...}
}
很明显,当B的方法void String setX(String s)重载了A的方法,但是按照我们刚才讲的理论A被编译成了
class A{
Object setX(Object t){...}
}
也就是说经过编译期之后类B的方法就不重载了A的方法,这是不被允许的,所以载编译的时候同样有两外一件事情发生:JDK会帮你添加一个帮助方法来重载A的方法,于是B就变成了:
class B extends A{
String setX(String s){...}
Object setX(Object o){
return setX((String)o);
}
}
大家看到多了个重载A类方法的一个方法:
Object setX(Object o){...}
这个方法就是所谓的bredge method
这个工作是在编译期完成的。所以如果你遍历A上的方法的时候如果发现多了方法千万不要感觉以外
注意这个方法的重载对EL表达式和TPL的运行不存在影响,因为不管用的哪个方法,经过TPL的转型之后结果都是一样的
分享到:
相关推荐
Java-jdk1.5安装包
windows 下的JDK1.5 直接解压 配置下JAVA_HOME环境变量就能用
包含 jdk1.5免安装、jdk1.6免安装、jdk1.8(32和64)
前几天上传过这个资源,因为是在jdk1.6上开发的, 测试了一下在jdk1.5上不能用, 今天重新用jdk1.5编译了一下, 这个是可以支持jdk1.5+的 将 pu-xlscommon-1.0.0.jar 添加到工程的 /lib 目录下 用法在附件中 XlsTest....
jdk1.5.exe jdk1.5 jdk1.5下载
绝版jdk1.5,非常不错的资源。用起来很好。是 Java语言对Bean类属性、事件的一种缺省处理方法。例如类A中有属性name,那我们可以通过getName,setName来得到其值或者设置新 的值。通过getName/setName来访问name属性,...
JDK1.5,JDK1.5
jdk1.5 java jdk1.5 java jdk1.5 java jdk1.5 java
测试可用的linux版jdk1.5,jdk-1_5_0_19-linux-i586-rpm.bin
今天,JDK1.5終於內建泛型特性,不僅編譯器不再需要 任何外力(外掛附件)的幫助,整個 Java標準程式庫也被翻新(retrofit),許多 角落針對泛型做了改寫。 讓我們把帶有「參數化型別」(parameterized types)的 ...
JDK作为JAVA环境的基本工具,JDK1.5虽然有点过时,但是其本身运行稳定等深受好评!!!
jdk1.5.0.22 是jdk1.5的最后一版,jdk1.5 windows 64位官方正式版,绝对有效,jdk1.5 windows 64位官方正式版,绝对有效
jdk1.5api,方便搜索版,不解释,谁用谁知道
Windows 64位环境的JDK1.5。Java SE Development Kit(jdk下载)是Java语言软件开发工具包,是整个Java的核心所在,一些开发应用都需要安装Java JDK环境。自从Java推出以来,JDK已经成为使用最广泛的Java SDK,JDK是...
jdk 1.5 中文 api chm jdk 1.5 中文 api chm
很实用的JAVA API中文参考文档,如果你开始讨厌HTML版本的API中文文档,试试这个吧,强大的索引功能使你开发更加愉快,分两卷,要都下了才能解压。
jdk1.5.0.22 是jdk1.5的最后一版
JDK1.5 API完整版JDK1.5 API完整版JDK1.5 API完整版
详细介绍java对象的使用和说明详细介绍java对象的使用和说明详细介绍java对象的使用和说明详细介绍java对象的使用和说明详细介绍java对象的使用和说明
JAVA中文帮助文档 jdk1.5