Simple
回归自我,努力奋斗
posts - 0,comments - 0,trackbacks - 0
    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)  编辑  收藏

只有注册用户登录后才能发表评论。


网站导航: