Java泛型小结(一)

在Java SE 1.5之前,没有泛型的情况的下,通过对类型Object的引用来实现参数的“任意化”,“任意化”带来的缺点是要做显式的强制类型转换,而这种转换是要求开发者对实际参数类型可以预知的情况下进行的。对于强制类型转换错误的情况,编译器可能不提示错误,在运行的时候才出现异常,这是一个安全隐患。   

泛型的好处是在编译的时候检查类型安全,消除源代码中的许多强制类型转换。这使得代码更加可读,并且减少了出错机会。

泛型小结将从如下几个方面入手: [color=red]通配符号的使用将放入下一篇博文中介绍[/color]。

[b][list]
[*]泛型的修饰范围
[*]使用&实现多重限制
[*]类型擦除
[color=red][*]<? super T>, <? extends T>, <?>通配符的使用[/color][/list][/b]

[u][b]泛型修饰的范围[/b][/u]

java 泛型是java SE 1.5的新特性,泛型的本质是参数化类型,也就是说所操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。


[b]a) 泛型接口的例子[/b]
public interface List<E> extends Collection<E> {
...

Iterator<E> iterator();

boolean add(E e);

boolean addAll(Collection<? extends E> c);

...
}


[b]b) 泛型类的例子[/b]
public class ArrayList<E> extends AbstractList<E>
implements List<E>, RandomAccess, Cloneable, java.io.Serializable
{
...
public Iterator<E> iterator() {
return new Itr();
}

public boolean add(E e) {
ensureCapacityInternal(size + 1); // Increments modCount!!
elementData[size++] = e;
return true;
}

...

public boolean addAll(Collection<? extends E> c) {
Object[] a = c.toArray();
int numNew = a.length;
ensureCapacityInternal(size + numNew); // Increments modCount
System.arraycopy(a, 0, elementData, size, numNew);
size += numNew;
return numNew != 0;
}

...
}


[b]c) 泛型方法的语法[/b]

[b][访问权限修饰符][static][final]<[color=blue]类型参数列表[/color]>[color=blue]返回值类型 [/color] [color=indigo]方法名[/color]([形式参数列表])[/b]
其中,[]内的内容是可选的。

下面举几个Collections工具类中的几个泛型方法例子:

    public static <T> void sort(List<T> list, Comparator<? super T> c) {
Object[] a = list.toArray();
Arrays.sort(a, (Comparator)c);
ListIterator i = list.listIterator();
for (int j=0; j<a.length; j++) {
i.next();
i.set(a[j]);
}
}



    public static <T extends Comparable<? super T>> void sort(List<T> list) {
Object[] a = list.toArray();
Arrays.sort(a);
ListIterator<T> i = list.listIterator();
for (int j=0; j<a.length; j++) {
i.next();
i.set((T)a[j]);
}
}


    public static <T> T min(Collection<? extends T> coll, Comparator<? super T> comp) {
if (comp==null)
return (T)min((Collection<SelfComparable>) (Collection) coll);

Iterator<? extends T> i = coll.iterator();
T candidate = i.next();

while(i.hasNext()) {
T next = i.next();
if (comp.compare(next, candidate) < 0)
candidate = next;
}
return candidate;
}


[u][b]
使用&实现多重限制[/b][/u]

如果一个类型有多余一个的限制条件,可以使用[b][color=blue]&[/color][/b]实现多重限制

    public static <T extends Object & Comparable<? super T>> T min(Collection<? extends T> coll) {
Iterator<? extends T> i = coll.iterator();
T candidate = i.next();

while (i.hasNext()) {
T next = i.next();
if (next.compareTo(candidate) < 0)
candidate = next;
}
return candidate;
}
public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll) {
Iterator<? extends T> i = coll.iterator();
T candidate = i.next();

while (i.hasNext()) {
T next = i.next();
if (next.compareTo(candidate) > 0)
candidate = next;
}
return candidate;
}



[u][b]类型擦除[/b][/u]

类型擦除(type erasure)。 Java中的泛型基本上都是在编译器这个层次来实现的。在生成的Java字节代码中是不包含泛型中的类型信息的。使用泛型的时候加上的类型参数,会被编译器在编译的时候去掉。这个过程就称为类型擦除。


比如:
import java.util.List;

public class TypeErasureTest {

public void test(List<String> ls) {
System.out
.println("Mthod test(List<String> ls) is calling.");

}

public void test(List<Integer> ls) {
System.out.println("Mthod test(List<Integer> ls) is calling.");
}
}


这段代码[color=red][b]无法编译通过[/b][/color]。

[img]http://dl2.iteye.com/upload/attachment/0089/1290/92e3129a-6deb-3d22-b3cf-8d433b4d8903.jpg[/img]


在编译后泛型类型是会被擦除的,在这个重载的例子中,因为参数List<Integer>和 List<String>编译之后都被擦除了,变成了一样的原生类型List<E>,擦除动作导致这两个方法的特征签名一样,这样两个相同的方法将不能满足重载,最后导致编译失败。


在编译后所有的泛型类型都会做相应的转化:

[list]
[*]List<String>, List<Integer>, List<T>擦除后的类型为List
[*]List<String>[] 擦除后的类型为List[]
[*]List<? extends E>, List<? super E> 擦除后的类型为List<E>
[*]List<T extends Serialiable & Clonable> 擦除后为List<Serialiable>
[/list]
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值