泛型:
jdk1.5出现的安全机制.
好处:
1.将运行时期的问题ClassCastException转到编译时期.
2.避免了强制类转换的麻烦
不是泛型的例子:
import java.util.ArrayList;
public class Demo {
public static void main(String[] args) {
ArrayList al = new ArrayList();
al.add(new Student("st1", 15));
al.add(new Student("st2", 18));
al.add(new Student("st3", 16));
for(Object s : al) {
Student t = (Student) s;
System.out.println("name:"+t.getName()+", age:"+t.getAge());
}
}
}
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
class Student extends Person{
public Student(String name, int age) {
super(name, age);
}
}
class Animal {
}
这个例子中, 由于要用的Object来接收
所以在进行输出的时候就需要进行强制类型转换
for(Object s : al) {
Student t = (Student) s; //前面是Student类型,所以就必须进行强转
System.out.println("name:"+t.getName()+", age:"+t.getName());
}
例如:
al.add(new Animal());
这时如果编译是完全没用问题的!!!
但是由于在我们的foreach循环中,里面的Object是强制转换为学生的,
但是我们加入的是动物,想象一下,把动物变成学生是多么可怕的一件事…
这个就会使我们出现运行出错.
运行结果:
大致错误信息: Animal cannot be cast to Student(无法将动物投掷给学生)
这时泛型的安全机制就显示出区别来了
泛型的例子:
import java.util.ArrayList;
public class Demo {
public static void main(String[] args) {
ArrayList<Student> al = new ArrayList<Student>();
al.add(new Student("st1", 15));
al.add(new Student("st2", 18));
al.add(new Student("st3", 16));
for(Person s : al) {
System.out.println("name:"+s.getName()+", age:"+s.getName());
}
}
}
class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public int getAge() {
return age;
}
}
class Student extends Person{
public Student(String name, int age) {
super(name, age);
}
}
class Worker extends Person{
public Worker(String name, int age) {
super(name, age);
}
}
class Animal {
}
显示结果:
可以看到,我们还没有编译, 他就给我们错误提示了
所以我们说泛型的好处之一 :
将运行时期的问题ClassCastException转到编译时期.
如果我们是要加入,学生,以及工人,还有人呢?
这时我们可以在<>里面写Person
ArrayList<Person> al = new ArrayList<Person>();
al.add(new Student("st1", 15));
al.add(new Student("st2", 18));
al.add(new Student("st3", 16));
al.add(new Person("perhhh1", 25));
al.add(new Person("perhhh2", 26));
al.add(new Person("perhhh3", 28));
al.add(new Worker("wo1", 30));
al.add(new Worker("wo1", 30));
al.add(new Worker("wo1", 30));
for(Person s : al) {
System.out.println("name:"+s.getName()+", age:"+s.getAge());
}
所以我们说泛型的另一个好处是:
避免了强制类转换的麻烦
这就引发了我们的另一个问题泛型<>什么时候用?
1.当操作的引用的数据类型不确定的时候,就用<>.
将要操作的引用数据类型传入即可.
其实<>就是一个接收具体引用数据类型的参数范围
2.在程序中,只要用到带有<>的类或者接口,就要明确传入的具体引用数据类型
泛型技术是给编译器使用的技术,用于编译时期,确保了类型的安全
运行时,会将泛型去掉,生成的class文件中是不带泛型的,这个称为泛型的擦除.
为什么擦除?
因为为了去兼容运行的类加载器
泛型的补偿:
在运行时通过获取元素的类型进行转换动作.不用使用者在强制类型转换了