java -- 泛型

为什么要引入泛型

先看一个例子,有如下代码:

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
public class Demo{
public static void main(String[] args){
Student stu = new Student("zhangsan", 32);
Student stu2 = new Student("lisi", 24);

Collection c = new ArrayList();
c.add(stu);
c.add(stu2);

Iterator it = c.iterator();
while(it.hasNext()){
String str = (String)it.next();
System.out.println(str);
}
}
}

class Student{
String name;
int age;

public Student(){

}

public Studnet(String name, int age){
this.name = name;
this.age = age;
}
}

输出结果如下:

1
2
Exception in thread "main" java.lang.ClassCastException: Student cannot be cast to java.lang.String
at GenericTest.main(GenericTest.java:16)

这是一个java中的类型转换异常,发生的原因是我们无法将一个Student类强转为String类,因为它们之间没有继承关系。

针对这种问题,java为我们提供了一种叫做泛型的机制,在编译期间就明确集合中存储元素类型,规避掉了这种不安全的转换情景。

修改如下:

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
public class GenericTest {
public static void main(String[] args){
Student stu = new Student("zhangsan", 32);
Student stu2 = new Student("lisi", 24);

//在声明及初始化集合变量时,就通过“<Student>”指明元素类型
Collection<Student> c = new ArrayList<Student>();
c.add(stu);
c.add(stu2);

//由于迭代器的底层操作的是集合的副本,也可以通过泛型机制指明元素类型
Iterator<Student> it = c.iterator();
while(it.hasNext()){
Student s = it.next();
System.out.println(s.name+"---"+s.age);
}
}
}

class Student{
String name;
int age;

public Student(){

}

public Student(String name, int age){
this.name = name;
this.age = age;
}
}

泛型给我们带来了什么

泛型的好处归纳起来,有如下几点:

  • 规避了不安全类型转换问题
  • 减少IDE警告
  • 可以简化代码书写(不用手动进行类型转换)

什么时候可以使用泛型

是否可以使用泛型,具体以API为准;原理上只要带有<E>标志的类或接口,都可以使用泛型。