1.一个简单的范型示例
在以前,你可能遇到过这样的代码:









注意,第三行需要强制转换。而使用范型:









这里将list声明成String类型的List。List是有一个类型参数的范型接口。这个例子中类型参数是String。
2.定义简单的范型
看j2se5.0中List和Iterator接口的实现(片断):



















上面的代码我们比较熟悉,但是其中增加了尖括号。尖括号中的内容定义了接口List和Iterator的形式类型参数。类型参数可以用在范型声明中,如类和接口的声明。
一旦声明了范型,你就可以使用它。在上面的例子中使用了List<String>。这里使用String是实参,代替了形参E。如果使用List<Integer>,则用实参Integer代替了形参E。
不管List<Integer>还是List<String>,它们的类只有一个。考虑下面的代码:





输出结果为true。
一般来说,形式类型参数都是大写,尽量使用单个字母,许多容器类都使用E作为参数。
3.范型和继承
考虑下面的代码,你认为它会出错吗?



当然,String类继承Object类,这样做不会出错。但下面的代码呢?



4.通配符
考虑下面一个方法:











事实上,上面这个方法并不通用,它只能打印Collection<Object>类型的集合,象其他的如Collection<String>、Collection<Integer>并不能被打印,因为对象类型不一致。
为了解决这个问题,可以使用通配符:











Collection<?>被称作未知类型的集合。问号代表各种类型。
上面的读取集合中的数据时,我们采用Object类型。这样做时可以的,因为不管未知类型最终代表何种类型,它的数据都继承Object类,那么再考虑一下下面的代码:



这样做时错误的,因为我们不知道?代表何种类型,所以我们不能直接将Object增加到集合中,这会出现类型不匹配的情况。
5.有限制的通配符
考虑下面的代码:



































这里使用? extends Man代替Man,表明接受任何Man的子类做为参数。
和前面的代码类似,下面的代码也是不正确的:














6.范型方法
考虑下面的代码,我们将一个数组的内容加到一个集合中









可以使用范型方法解决:









考虑下面的例子:






改写成通用方法:






然而,在这里每个方法T只使用了一次,返回值不依赖形式参数,其他参数也不依赖形式参数。这说明实参被用作多态,这种情况下就应该用通配符。