用途
数据结构类型的参数化
产生根源
例如在使用集合框架的时候,Vector里可以添加各种类型,
v.add(new Person("tom",20))
Person p = (Person)v.elementAt(0)
如此使用,到处都需要强制转换。如果出现异常只能在运行时才会抛出。
集合中的泛型
例如Vector<String> v = new Vector<String>();
这里的<String>是实际类型参数,限定了v中添加的都是String.
泛型类
例如:
Person<T>{
private T secret;
}
可以衍生出不同的类型。例如
Person o = Person<Object>();
Person s = Person<String>();
但他们之间并不存在继承关系。
MAP中常用K V。LIST中用E 代表元素。泛型类中用T
泛型方法
例如为了限定某个方法的两个参数类型一致,可以用:
public <T> T evaluate(T a,T b)
也可以将T定义在泛型类中。
通配符
例如现在写一个方法,来遍历一些不同类型的泛型实例,
public overview(Vector<String> v)
如果将实际类型参数加入,则不能通用。
public overview(Vector v)
去掉实际类型参数,是一种方法。这种情况,在方法体里加入
v.add(new String("aaa"))
v.add(new Integer(5))
都不会出错,可能在运行时会产生错误,这就破坏了类型安全性限制,使泛型的限制
并没有在编译时发现错误。
引入通配符,public overview(Vector<?> v)
与public overview(Vector v)有什么区别呢?
主要是引入通配符后,Vector<?>类型的变量在调用的时候是受到限制的,凡是必须
知道具体类型参数才能进行的操作会被禁止。
例如
Vector<String> vs = new Vector<String>();
vs.add("TOM");
Vector<?> v = vs;
v.add("BILL");//非法操作
Object o = v.elementAt(0)//合法
受限类型
例如:Person<T extends Number>
限制更严格一点,要求泛型必须继承Number
同样通配符也可以用于
限制
基本类型不能用于泛型
例如 List<int> a 这种,是会报错的,Syntax error on token "int", Dimensions expected after this token
习题
1.
QUESTION NO: 70
Given:
11. // insert code here
12. private N min, max;
13. public N getMin() { return min; }
14. public N getMax() { return max; }
15. public void add(N added) {
16. if (min == null || added.doubleValue() < min.doubleValue())
17. min = added;
18. if (max == null || added.doubleValue() > max.doubleValue())
19. max = added;
20. }
21. }
Which two, inserted at line 11, will allow the code to compile? (Choose two.)
A. public class MinMax<?> {
B. public class MinMax<? extends Number> {
C. public class MinMax<N extends Object> {
D. public class MinMax<N extends Number> {
E. public class MinMax<? extends Object> {
F. public class MinMax<N extends Integer> {
解答,看A,B,E显然不对,因为都用了?,代码里的N就没有来源了
C,如果受限类型extends Object,那就没有doubleValue()方法。
答案是 D F
2.
<p align="left"><strong>QUESTION NO: 71</strong></p>Given:
3. import java.util.*;
4. public class G1 {
5. public void takeList(List<? extends String> list) {
6. // insert code here
7. }
8. }
Which three code fragments, inserted independently at line 6, will compile? (Choose three.)
A. list.add("foo");
B. Object o = list;
C. String s = list.get(0);
D. list = new ArrayList<String>();
E. list = new ArrayList<Object>();
用通配符后,那些必须知道类型才能进行的操作就被禁止了,比如add,因此A不对
答案是 BCD