Simple
回归自我,努力奋斗
BlogJava
首页
新随笔
新文章
联系
聚合
管理
posts - 0,comments - 0,trackbacks - 0
<
2025年7月
>
日
一
二
三
四
五
六
29
30
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
1
2
3
4
5
6
7
8
9
留言簿
给我留言
查看公开留言
查看私人留言
文章分类
Professional Java Development with the Spring Framework 个人翻译(1)
文章档案
2011年8月 (2)
搜索
最新评论
java泛型擦除的实质与疑惑
JDK5引入泛型,给我们编程带来了很大的方便,它让我们的类更加通用.但曾一段时间对java泛型中独有的擦除概念,迷惑不解.什么是擦除?擦除的实质是什么?为什么要擦除?经过一段时间的研究后,总算有所体会,下面与大家分享一下,学习中的经验.
个人理解擦除说的通俗一点就是转型,就是将泛化的不确定类型,转型到某一确定的类型,这一确定的类型我们称之为边界,这一转型的过程就是擦除。这样说你可能还不好理解,我来写个例子,根据例子来剖析擦除的实质。
源代码
public
class
Bootstrap
{
public
static
void
main(String[] args)
{
List
<
Number
>
list
=
new
ArrayList
<
Number
>
();
list.add(
1
);
list.add(
new
Float(
2.1
));
Number number
=
list.get(
0
);
}
}
反编译后的代码
public
class
Bootstrap
{
public
Bootstrap()
{
}
public
static
void
main(String args[])
{
List list
=
new
ArrayList();
list.add(Integer.valueOf(
1
));
list.add(
new
Float(
2.1000000000000001D
));
Number number
=
(Number)list.get(
0
);
}
}
通过比较反编译后发现,源代码在编译后产生的代码中,并不存在泛型。它就像我们以前没有泛型时,编写的代码一样。原有的泛型信息并不存在,我们说它被擦除了,那被擦除成什么了呢?我们看
Number number = list.get(0);
这句代码,当我们试图从list中获取元素时,java编译器会自动的给我们进行强制转型,这种转型后的目标类都是Number,致使我们获取的元素都是Number类型了,原有的类型Integer和Float都被擦除掉了,并没有任何地方存储了元素的确切类型,我们无法知道获取元素的确切类型,只知道获取的是个边界类型Number。这就是java泛型的擦除实质。这儿也可以看出JAVA的泛型在运行时并不使用,它只在编译的时候发挥作用。
为什么java会擦除泛型信息呢?其实这是可以理解的,因为在以前的JDK版本中,并不存在泛型这一概念,为了兼容以前的版本,让新写的泛型程序能在以前得版本上运行而采用了这种折中的办法。
然而,由于泛型的不彻底,也给我们带来了一定的困惑,其中最大的困惑就是,我们不能使用new 关键字来构造泛型.如
new T();
这样做是不合法的编译器无法通过。虽然说在现有的JDK版本上,编译错误可以理解,但是着实让人不爽.泛型中还存在其他的一些问题,有兴趣的同学可以研究一下:
http://www.ibm.com/developerworks/cn/java/j-jtp01255.html
posted on 2011-08-08 10:00
Mr.simple
阅读(206)
评论(0)
编辑
收藏
新用户注册
刷新评论列表
只有注册用户
登录
后才能发表评论。
网站导航:
博客园
IT新闻
Chat2DB
C++博客
博问
管理