为什么要使用泛型

什么是泛型

泛型的本质是参数化类型,操作的数据类型被指定为一个参数。这种参数类型可以用在类、接口和方法的创建中,分别称为泛型类、泛型接口、泛型方法。 对于强制类型转换错误的情况,编译器可能不提示错误,在运行的时候才出现异常,这是一个安全隐患。使用泛型的好处是在编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的,提高代码的重用率。

栗子

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
public class TestMain {

public static void main(String[] args){
TestList testList = new TestList();
testList.add("aaa");
testList.add(100);
//我们向testList中添加了不同类型的对象,当我们要取出某个对象时
//取第一个对象时,会发生ClassCastException异常,但是编译器却无法检测出来
//Integer num = (Integer)testList.getObj(0);
Integer num = (Integer)testList.getObj(1);

ArrayList<String> list = new ArrayList<>(10);
//使用泛型的java.util.ArrayList在添加不同类型时,编译不能通过
//list.add(100);
list.add(String.valueOf(100));

}
}

/**
* 简易版list
*/

class TestList{
private Object[] value =new Object[10];
private int size;
public TestList(){

}

public void add(Object obj){
value[size] = obj;
size++;
}

public Object getObj(int index){
return value[index];
}
}

向上/向下强制转型

Level1是接口,Level2实现了Level1,Level3继承自Level2

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
	public class TestMain {

public static void main(String[] args){

TestList<Level2> testList = new TestList();
Level2 level2 = new Level2();
Level3 level3 = new Level3();
//此时必须是Level2的子类,编译不通过
testList.add(level2);
testList.add(level3);

TestMain testMain = new TestMain();
//编译出错,因为test方法要求参数list必须为Level3的子类,而testList初始化的时候T=Level2
//testMain.test(testList);
//没问题
testMain.test2(testList);

TestList<Level3> test3 = new TestList();
//此时没问题
testMain.test(test3);
}

public <T extends Level3> void test(TestList<T> list){
Level3 l = list.getObj(0);
l.showMsg();
}
public void test2(TestList<? extends Level2> list){
Level2 l = list.getObj(0);
l.showMsg();
}
}

/**
* 简易版list
* 向下转型,表示类必须是Level的子类
* 向上转型,<? super Double>
*/

class TestList<T>{
private Object[] value =new Object[10];
private int size;

public void add(T obj){
value[size] = obj;
size++;
}

public T getObj(int index){
return (T)value[index];
}
}

总结