第二十三条:请不要在新代码中使用原生态类型
声明中具有一个或者多个类型参数(type parameter)的类或者接口,就是泛型。
泛型类和泛型接口统称为泛型(generic type)。
每种泛型定义一组参数化的类型,构成格式为:先是类或者接口的名称,接着用尖括号(<>)把对应于泛型形式类型参数的实际类型参数列表括起来。
原生态类型就像从类型声明中删除了所有的泛型信息一样。实际上,原生态类型List与Java平台没有泛型之前的接口类型List完全一样。
如果不提供类型参数,只是使用集合类型和其他泛型的原生态类型仍然是合法的,但是不应该这么做。如果使用原生态类型,就失掉了
泛型在安全性和表述性方面的所有优势。既然不应该使用原生态类型,为什么Java还要允许使用原生态类型呢?因为这是为了兼容性,因为
在JDK1.5之前,Java已经进入它的第二个十年,而在这之前,Java没有泛型,为了以前的代码的仍然能够正常使用,促使Java仍然支持原生态
类型。
虽然不应该在新代码中使用像List这样的原生态类型,使用参数化的Object类型以允许插入任意对象,如List<Object>,这还是可以的。
原生态List类型和List<Object>类型之间的区别:不严格的说,前者逃避了泛型检查,后者则明确告知编译器,它能够持有任意类型的对象。
可以将List<String>类型的对象赋给原生态List类型的变量,但是不能将List<String>类型的对象赋给List<Object>类型的变量。因为泛型
有自己的子类型化的规则,List<String>是原生态List的一个子类型,而不是参数化类型List<Object>的子类型。因此使用像List这样的原生态
类型,就会失掉类型安全性,但是如果使用像List<Object>这样的参数化类型,则不会。
在不确定或者不在乎集合中的元素类型的情况下,你也许会使用原生态类型。但是使用原生态类型是很危险的。
为了避免使用原生态类型,但是在不确定或者不在乎这个集合中应该存放哪种类型的对象时,Java提供了一种安全的替代方法,称作无限制的通配符
类型。如果要使用泛型,但不确定或者不关心实际的类型参数,就可以使用一个问号代替。
public static void testMethod(Set<?> s1 , Set<?> s2)
{
………
}
客户端程序员 可以传入任意实际类型的类型参数。
不要在新代码中使用原生态类型(raw type) 两个小小的例外,两者都源于“泛型信息可以在运行时被擦除”这一事实。
1.在类对象的使用时,必须使用原生态类型。规范不允许使用参数化类型。List.class,String[].class,int.class都是合法的,但是List<String>.class,
List<?>.class则不合法。
2. s1 instanceof Set是合法的,s1 instanceof Set<?> 是不合法的。
一旦确定s1是Set集合,就必须将它转化成为通配符类型Set<?>,而不是转换成原生态类型Set。