Jdk1.5中的新特性 --泛型

一,Java中的泛型:
在Java中能使用到泛型的多是容器类,如各种list map set,因为Java是单根继承,所以容器里边可以放的
内容是任何Object,所以从意义上讲原本的设计才是泛型。但用过Java的人是否感觉每次转型很麻烦呢?
而且会有些错误,比如一个容器内放入了异质对象,强制转型的时候会出现cast异常。而这中错误在编译器是
无从发现的。所以jdk1.5中提供了泛型,这个泛型其实是向c++靠拢了.好,我们先看几个实例再细说原理。

二,泛型的用法:(多个实例)


1 实例A
2 ArrayList < String > strList = new ArrayList < String > ();
3 strList.add( " 1 " );
4 strList.add( " 2 " );
5 strList.add( " 3 " );
6 // 关键点(1) 注意下边这行,没有强制转型
7 String str = strList.get( 1 );
8 // 关键点(2)然後我们加入,这个时候你会发现编译器报错,错误在编译器被发现,错误当然是发现的越早越好
9 strList.add( new Object());
1 实例B
2 ArrayList < Integer > iList = new ArrayList < Integer > ();
3 // 关键点(3) 注意直接把整数放入了集合中,而没有用Integer包裹
4 iList.add( 1 );
5 iList.add( 2 );
6 iList.add( 3 );
7 // 关键点(4)同样直接取出就是int
8 int num = iList.get( 1 );
1 实例C
2 // 关键点(5)展示一下key-value的时候要怎么写,同时key和value也可以是基本类型了。
3 HashMap < Integer,Integer > map = new HashMap < Integer,Integer > ();
4 map.put( 1 , 11 );
5 map.put( 2 , 22 );
6 map.put( 3 , 33 );
7 int inum = map.get( 1 );
8
三,看完了实例了,详细来说说为什么吧
首先jdk1.5中的泛型,第一个解决的问题,就是Java中很多不必要的强制转型了,具体的实现,我们以ArrayList
为例,下边是ArrayList中的片断代码:

1ArrayList类的定义,这里加入了<E>
2public class ArrayList<E> extends AbstractList<E>
3 implements List<E>, RandomAccess, Cloneable, java.io.Serializable
4
5//get方法,返回不再是Object 而是E
6public E get(int index) {
7 RangeCheck(index);
8 return elementData[index];
9}
10//add方法,参数不再是Object 而是E
11public boolean add(E o) {
12 ensureCapacity(size + 1); // Increments modCount!!
13 elementData[size++] = o;
14 return true;
15}
16

四,Boxing 和UnBoxing
看到上边的关键点(3)和(4)是否感觉惊奇呢,因为Java中烦人的除了强制转型,另一个就是基础类型了
放入容器的时候要包装,取出了还要转回。Jdk1.5中解决了这个问题.如上边的使用方法

五,泛型的生命周期(使用注意事项)
如果我们试着把ArrayList<String> list的内容序列化,然後再读取出来,在使用的过程中会发现出错,
为什么呢?用Stream读取一下回来的数据,你会发现<String>不见了,list变成了普通的ArrayList,而不是
参数化型别的ArrayList了,为什么会这样呢 ?见下边的比较

六,C++的泛型和Java的泛型
在泛型的实现上,C++和Java有着很大的不同,
Java是擦拭法实现的
C++是膨胀法实现的
因为Java原本实现就是泛型的,现在加入型别,其实是"窄化",所以采用擦拭法,在实现上,其实是封装了原本的
ArrayList,这样的话,对于下边这些情况,Java的实现类只有一个。


1ArrayList<Integer> .; public class ArrayList
2ArrayList<String> ..; --同上--
3ArrayList<Double> ..; --同上--
4而C++采用的是膨胀法,对于上边的三种情况实际是每一种型别都对应一个实现,实现类有多个
5list<int> li; class list; //int 版本
6list<string> ls; class list; //string 版本
7list<double> ld; class list; //double 版本
这就造成了,在序列化后,Java不能分清楚原来的ArrayList是
ArrayList<Integer>还是ArrayList

七,题外话,在很多东西的实现上C++和Java有很多不同
例如运算符的问题i=i++问题,详细看这里
例如在C++中能很好实现的double-checked locking单态模式,在Java中几乎很难实现 详细看这里
还有就是上边提到的泛型实现上。


八,Jdk 1.5加入了不少新东西,有些能很大的提高开发质量,例如Jdk1.4 ,Jdk.15中StringBuffer的不同
因为从1。4转入1。5不久,所以慢慢会发一些在1。5的使用过程中发现的东西。

在JDK1.5中加入了泛型,能帮助我们简化代码,能解决不少问题,那JDK1.5中是如何实现的呢 ?
JDK1.5中泛型的实现是擦拭法实现的,不同与c++中的泛型。说擦拭法可能有点难理解,所以从下边的角度理解一下:
我们写一个程序 1 package com.jdk15;
2
3 import java.util.ArrayList;
4
5 public class Generic {
6 public static void main(String[] args){
7 ArrayList<String> list = new ArrayList<String>();
8 list.add("a");
9 list.add("b");
10 String str = list.get(0);
11 }
12 }编译成.class的文件
然后用Jad反编译后的结果:
1 // Decompiled by Jad v1.5.8g. Copyright 2001 Pavel Kouznetsov.
2 // Jad home page: http://www.kpdus.com/jad.html
3 // Decompiler options: packimports(3)
4 // Source File Name: Generic.java
5
6 package com.jdk15;
7
8 import java.util.ArrayList;
9
10 public class Generic
11 {
12
13 public Generic()
14 {
15 }
16
17 public static void main(String args[])
18 {
19 ArrayList list = new ArrayList();
20 list.add("a");
21 list.add("b");
22 String str = (String)list.get(0);
23 }
24 }
25 看到这个是否明白了吗 ?
在JDK1.5中,只是在编译期作了下手脚,就是在你编译之前,自动补充了转型,然后编译实现的。
所以JDK1.5中的泛型只简化了代码的编写,并没有提高性能的原因。因为转型并没有去掉。


最后,我们还可以自己写类似ArrayList这样的泛型类,至于如何自定义泛型类,泛型方法请参见候捷先生的文章
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值