Java 泛型学习笔记(二)

时间:2022-09-20 08:47:40
Java1.5引入了泛型之后,为程序的安全性又增加了一个新的保障,减少了发生运行时类型错误的可能性,这篇文章并不是要讲述泛型的基本操作,而是要了解一些在进行泛型处理时可能会遇到的一些稍微复杂些的问题。在第一篇文章中,主要了解一些泛型和原生态类型的关系问题。

何为原生态类型(raw type),就是不带有类型信息的"泛型",比如相对于List<Integer>的List就是原生态类型。实际上原生态类型的List与JDK1.5之前的版本是相同的。

很明显可以得出的结论是原生态类型是不安全的,例证我这里也不给出了,这里只会说一些泛型的一些特点和与原生态类型之间的联系。

1. 无限制的通配符类型

在泛型中,有一种无限制的通配符类型,比如List<?>,这里的"?"就代表了对这个List中的元素没有限制或者根本不关心。在提供了方便性的同时它也有一个很大的限制,那就是使用了无限制通配符类型的泛型比如List<?>,是不能添加任何元素进去的。
比如:
	public void testMethod(Set<?> set){		set.add("e");
}
是不会通过编译的。因为通过这种方式很容易就会破坏泛型的类型限制。

但是,也有例外,null是可以插入进去的。


2. 泛型信息的运行时擦除
Java中的泛型有一个这种特点,它的泛型信息在运行时是会擦除掉的,也就是说只有在编译期,泛型才会发生作用,真正运行的时候List<Integer>和List也是没有区别的,不过这也足够了。

因为泛型的这个特点,泛型与原生态类型就有了2个联系:
(1) 类的字面量只能用原生态类型而不是泛型。
比如,List.class,Map.class。你可能也没见过List<Integer>.class的写法吧?因为这种是不合法的。
(2) instanceof操作符只能跟原生态类型。
比如写一个下面的方法: 

	public static void testMethod(Collection<?> collection) {
if (collection instanceof Set) {
Set<?> s = (Set<?>) collection;
for (Object e : s) {
System.out.println(e);
}
}
}

public static void main(String[] args) {
Set<String> set = new HashSet<String>();
set.add("1");
set.add("2");
set.add("3");
set.add("4");
set.add("5");
testMethod(set);
}

这里instancdof后面跟的就是原生态类型,而确定了类型之后就要将其转换为相应的泛型类型。