轻松掌握 Java 泛型 (第 2 部分)
上一篇 / 下一篇 2008-01-10 18:00:12 / 个人分类:做着
轻松掌握 Java 泛型 (第 2 部分)ITPUB个人空间)Fya,L#tUb d]{
来源:** 收集整理
l$x,y*oqj.k
g0 ITPUB个人空间|CY5X8R!E
+cRO j.X)\)Sf-{0 ITPUB个人空间{wu f,z,Ab
ITPUB个人空间\Cm*y Z"UJ:^
J2SE 1.5 — 代号为“
d`8v$[3{0JSR-14 原型编译器中预先ITPUB个人空间X2wh-RU/@5pP
f
型类型的基础知识,以及为
y+k&E9K;B"k_t0明了为 Tiger 制定的泛型ITPUB个人空间Jtg9}+D
型类型的上下文。ITPUB个人空间/Y)g.Q6Aq5] Cm
B@
Tiger” — 计划在 2003 年年
y/uZcA$k:c0展示的那样,现在可下载获得)
Kp.c8F:s}:jR0什么它们是对 Java 语言的一个ITPUB个人空间/QCcQ&x
类型的实现怎么会包含数个“缺
底发布,它将包括泛型类型(如在
|BU7}fL0。在第 1 部分中,我们讨论了泛ITPUB个人空间6P,d\Oq1_!zr
重要且迫切需要的补充。我们还说
B`'|XLPR2LAfT0陷”,这些缺陷限制了可以使用泛
为了帮助新程序员有效ITPUB个人空间B3E2u~'JQ8k5mS:t
Tiger 和 JSR-14 中是被禁ITPUB个人空间 _r[5kb5U'R6jY
)为了在 JVM 上兼容地实ITPUB个人空间?N8u\+Q
地使用泛型类型,我将详细说明
4cD!dQe`8mO4Q0止的,并将说明为什么这些限制ITPUB个人空间QW1l-kP`"?
现泛型类型所使用的实现策略的ITPUB个人空间-Q+D%|J4{Cl
到底泛型类型的哪些用法在
X~o7s~)U0是 JSR-14(理所当然还有 Tiger
2g5GQ~!Ai;~0\C:B0必然结果。
4T'G[ [ u9pGT"A0
泛型类型的限制
让我们先查阅一下 Tiger 和 JSR-14 中泛型类型的使用限制:
不应在静态成员中引用封闭类型参数。
8bE8EtK Uyt0 不能用基本类型实例化泛型类型参数。 ITPUB个人空间B2I+nP-_t.M:N^
不能在数据类型转换或 instanceof 操作中使用“外露”类型参数。 ITPUB个人空间7_)S2e,kG&}
不能在 new 操作中使用“外露”类型参数。
y3x#d"\]KO-s:UX0 不能在类定义的 impleITPUB个人空间N]p2g?7U.~|_W
ments 或 extends 子句中使用ITPUB个人空间&R\ FVjB1B
“外露”类型参数。ITPUB个人空间D"ORR0LfI$l
ITPUB个人空间/{I0ZGHVP9IU@
为什么会有这些限制呢?这要归因于
/m2lI(PW.Wrf"Vu0的机制。由于 JVM 根本不支持泛型类型ITPUB个人空间2n;E8?'m }KE)gw
泛型类型的支持 — 它们用泛型类型信息ITPUB个人空间z1| S*O*Qv]"t
生成只包含普通类型的类文件。ITPUB个人空间U#dI V,Hs
Tiger 和 JSR-14 为在 JVM 上实现泛型类型所使用ITPUB个人空间}'s2?;_~ p
,所以这些编译器“耍了个花招”,使得似乎存在对
#S`l|g6y6_?$_M0检查所有的代码,但随即“擦除”所有的泛型类型并
例如,将象 List< T> 这样的泛型类型擦除得只剩下 List。“外露”类型参数 — 单独出现而不是位于某个类型中的类型参数(如类 List< T> 中的类型参数 T)— 被简单地擦除成它们的上界(就 T 而言,其上界就是 Object)。
!?,E-RP
u+k/v0 这一技术的功能极其强大;我们可以使几乎所有泛型类型的精度得到增强,但又与 JVM 保持兼容。事实上,我们甚至可以交替地使用非泛型的旧类(比如 List)和其对应的泛型类(List< T>);两者在运行时看起来是一样的。
ITPUB个人空间 kv8U(_Gnpy[
遗憾的是,正如以上的限制所示,获ITPUB个人空间`]?*n*jB!|
系统中引入了缺陷,这些缺陷限制我们使ITPUB个人空间#^)rW?4kX*mK3[
得这一功能是有代价的。以这种方式进行擦除在类型ITPUB个人空间Qr9R
IiABK
用泛型类型的安全性。ITPUB个人空间p|DJ8te$jf
为了帮助说明每种限制ITPUB个人空间`M b|'v
Z)mG
限制。与后两个限制有关的ITPUB个人空间 mC:W)@5II
,我们查阅会出现这些限制的示ITPUB个人空间bb*nzWtB
问题过于复杂,因而需要更深入
6n;Oe6dw u$B#E0 例。在本文中,我们将讨论前三个
WFKIi4ug0的研究,留待下一篇文章讨论。ITPUB个人空间
c*m8C3^;@\1L4hR1A
静态成员中的封闭类型参数
编译器完全禁止在静态方法和静态内
Lb'D|Ju0码在 Tiger 中就是非法的:ITPUB个人空间BaD0w*{2?lRC
部类中引用封闭类型参数。所以,举例来说,以下代
清单 1. 在静态上下文中非法引用封闭类型参数 class C< T> {
static void m() {
Ru5xU2IT#Wef%L0 T t; ITPUB个人空间"J5S*T
c?fA(j
}
static class D { ITPUB个人空间$n+vL9^6Rh$?9{
C< T> t;
} ITPUB个人空间.^W%AT;B5rXF
}
当编译这一代码时,会生成两个错误:
在静态方法 m 中非法引用 T 的错误
U&W]4@%?}0 在静态类 D 中非法引用 T 的错误
2C,OI#ey0 当定义静态字段时,情ITPUB个人空间J#@#?Dz
中共享该类中的静态字段。
H,KJttg0明中引用类型参数,编译器ITPUB个人空间RuP'j;Ry3I
时导致奇怪的错误,如在不ITPUB个人空间DNP[g)h-a_(pt0`X
况变得更加复杂。在 JSR-14 和ITPUB个人空间"{z8v F@d
现在,在 JSR-14 编译器 1.0
OCS]'y#S3wX0不会报错,但它本应该这么做。
A}(pG8f7uy0包含数据类型转换的代码中出现
j_Rnt3c0 Tiger 中,在泛型类的所有实例ITPUB个人空间%L#m,S\+a8?
和 1.2 中,如果您在静态字段声
k-_*RN6b,e0字段被共享这一事实很容易在运行
,p,c
Uv`L V$ej x@0ClassCastException。
4~4Q|9v5]5z7u9y0
例如,以下程序将在这两个版本的 JSR-14 下通过编译而没有任何警告:
清单 2. 在静态字段中对封闭类型参数的有问题的引用 class C< T> {
static T member;
C(T t) { member = t; }
T getMember() { return member; }
public static void
*z7N6O,UsH*WnuX0 main(String[] args) {
6u&fy*^U K#_/w0 ITPUB个人空间*Y7Jn%Y)B,RD z
ITPUB个人空间`B?_-Cm:M;@e\/a
C< String> c = new C< String>("test");
System.out.print