学习目标:
1、了解泛型的概念
2、了解JDK中使用了泛型的类,如List等
3、能在项目中灵活使用泛型
学习过程:
一、泛型简介
1、什么是泛型
泛型(Generic type或者 generics)是指Java 语言的类型系统的一种扩展,在程序编码中一些包含类型参数的类,也就是说泛型的参数代表类,以支持创建可以按类型进行参数化的类。可以把类型参数看作是使用参数化类型时指定的类型的一个占位符,就像方法的形式参数是运行时传递的值的占位符一样。在java1.5后开始支持泛型,所有的集合类都支持泛型了。
2、泛型的优点
Java语言引入泛型的好处是安全简单,在Java SE 1.5之前,没有泛型的情况的下,通过对类型Object的引用来实现参数的“任意化”,“任意化”带来的缺点是要做显式的强制类型转换,而这种转换是要求开发者对实际参数类型可以预知的情况下进行的。对于强制类型转换错误的情况,编译器可能不提示错误,在运行的时候才出现异常,这是一个安全隐患。
泛型的好处是在编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的,提高代码的重用率。
二、泛型示例
1、不使用泛型的情况
我们先定义两个javaBean类,学生类Student代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public
class
Student {
private
int
id;
private
String name;
public
int
getId() {
return
id;
}
public
void
setId(
int
id) {
this
.id = id;
}
public
String getName() {
return
name;
}
public
void
setName(String name) {
this
.name = name;
}
}
教师类代码如下:
1
2
3
4
5
6
7
8
9
10
11
public
class
Teacher {
private
String name;
public
String getName() {
return
name;
}
public
void
setName(String name) {
this
.name = name;
}
}
定义一个Run类,我们定义三个学生对象和一个教师对象,然后定义一个学生列表,逻辑上面学生列表只能存储学生对象,但是代码中却放入了教师对象,但是程序也不会有任何错误提示,在遍历该列表时,我们需要类型判断和类型的强制转换,非常麻烦,代码如下:
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
public
class
Run {
public
static
void
main(String[] args) {
//
Student stu1 =
new
Student();
stu1.setId(
1
);
stu1.setName(
"刘德华"
);
Student stu2 =
new
Student();
stu2.setId(
2
);
stu2.setName(
"郭富城"
);
Student stu3 =
new
Student();
stu3.setId(
3
);
stu3.setName(
"张学友"
);
Teacher teacher=
new
Teacher();
teacher.setName(
"刘"
);
//不使用泛型,
ArrayList students =
new
ArrayList();
students.add(stu1);
students.add(stu2);
students.add(stu3);
students.add(teacher);
//可以任意添加。
for
(
int
i =
0
; i < students.size(); i++) {
Object object=students.get(i);
//最好进行类型判断,不然可能会发生转换失败
if
(object
instanceof
Student){
//需要强制类型转换
Student stu = (Student) object;
System.out.println(stu.getName());
}
}
}
}
2、使用泛型带来的好处
在java1.5后开始支持泛型,集合类的定义都支持泛型了。所以我们在定义ArrayList时可以使用泛型。修改上面的部分代码。
1
2
3
4
5
6
7
8
9
10
11
//Entity 这个列表只能放Student类或者Student的子类
ArrayList<Student> students=
new
ArrayList<Student>();
students.add(stu1);
students.add(stu2);
students.add(stu3);
//students.add(teacher);//这行在编译时就已经有错误了。
for
(
int
i =
0
; i < students.size(); i++) {
Student stu=students.get(i);
//会自动的隐式转换。
System.out.println(stu.getName());
}
除了List之外,其他集合类都支持泛型,比如HashMap类。示例代码如下:
1
2
3
4
HashMap<String, Student> map=
new
HashMap<String, Student>();
map.put(
"001"
, stu1);
map.put(
"002"
, stu2);
map.put(
"003"
, stu3);
使用泛型后,编译的时候检查类型安全,并且所有的强制转换都是自动和隐式的
3、自定义泛型
如果我们定义类时候需要使用泛型也是非常简单的。示例代码如下:
1
2
3
4
5
6
7
8
9
10
11
12
13
//定义类时候,使用泛型。
public
class
ClassRoom<T> {
private
T t;
public
ClassRoom(T t){
this
.t=t;
}
public
void
test(){
System.out.println(t.toString());
}
}
使用泛型和集合类的使用一样,示例代码如下:
1
2
3
4
5
ClassRoom<Student> classRoom=
new
ClassRoom<Student>(stu1);
ClassRoom<Teacher> classRoom2=
new
ClassRoom<Teacher>(teacher);
classRoom.test();
//调用的是Student类的toString方法。
classRoom2.test();
//调用的是Teacher类的toString方法。