一、泛型概念
1.将运行时期的问题(类型转换异常)转到了编译时期,避免了强制转换的麻烦。
2.泛型技术是给编译器使用的技术,用于编译时期,确保类型安全。运行时,会将泛型去掉,生产的class文件中不带泛型,这叫泛型的擦除(为什么擦除吗?为了兼容类加载器。)
3.泛型补偿:在运行时,通过获取元素的类型进行转换动作,不用使用者再强制转换了。个人理解:泛型就用一个符号或者具体对象指定了各种集合或比较器等中所操作的元素类型,编译时就能检测操作对象是否符合泛型的指定,提高了安全性。
4、<类型>作用:就是一个用于接受具体引用数据类型的参数范围。在程序中,只要用到了带有<>类或者接口,就要确定引用数据类型。
二、泛型的具体表现
1、集合中的泛型
ArrayList s = new ArrayList<>();
HashMap
class CompaByPer implements Comparator<Person>{
@Override
public int compare(Person p1, Person p2) {
int temp;
temp = p1.getAge()-p2.getAge(); //按照年龄比,若相等,按照名字比。
return temp==0?p1.getName().compareTo(p2.getName()):temp;
}
}
说明:代码所示,一个Comparator接口中的泛型,明确了要比较的对象引用数据类型。
3、类中的泛型
package GenericClass;
class Student{}
class Worker{}
class Tool<Person>{ //用来对类的引用数据类型进行操作,但是操作类均有多种
private Person p;
public Person getObj()
{
return p;
}
public void setObj(Person p) {
this.p = p;
}
}
public class GenericClassDemo {
public static void main(String[] args) {
Tool<Student> t = new Tool<>();
//明确之后,t对象只能操作Student的对象。
t.setObj(new Student());
}
}
说明:当类中的操作的引用数据类型不确定的时候,就使用泛型来表示。
4、方法中的泛型
在方法上定义泛型,可以接受所有类型的对象。(和object功能一样,后面还有新的运用)。
public <W> void printf(W str){
System.out.println("str:"+str);
}
说明:可以指定任意一个对象的引用数据类型。
5、泛型的通配符和上下限定
package GenericClass;
import java.util.Comparator;
import java.util.TreeSet;
public class GenericClassDemo1{
public static void main(String[] args) {
/*Comparator<? super Student> comparator =
new CompaByStu<Student>()
* super:向上,取出可以是Student和Person的方法
* */
TreeSet<Student> s = new TreeSet<>(new CompaByStu());
s.add(new Student("yy1",11));
s.add(new Student("yy13",13));
s.add(new Student("yy22",12));
/*这个容器存放的是Worker*/
TreeSet<Worker> w = new TreeSet<>(new CompaByPer());
w.add(new Worker("ww1",11));
w.add(new Worker("ww13",13));
w.add(new Worker("ww22",12));
/*这个容器存放的是Person*/
TreeSet<Person> p = new TreeSet<>(new CompaByPer());
/*Collection<? extends Person> c = new TreeSet<Student>();
*Collection<? extends Person> c = new TreeSet<Worker>();
* */
p.addAll(s); //学生可以放在人类内
p.addAll(w); //工人也可以放在人类
GenericClassDemo.IteratorMethod(s);//迭代器取出元素
System.out.println("----华丽分界线----");
GenericClassDemo.IteratorMethod(w);
System.out.println("----华丽分界线----");
GenericClassDemo.IteratorMethod(p);
}
}
//人类比较器
class CompaByPer implements Comparator<Person>{
@Override
public int compare(Person p1, Person p2) {
int temp;
temp = p1.getAge()-p2.getAge(); //按照年龄比,若相等,按照名字比。
return temp==0?p1.getName().compareTo(p2.getName()):temp;
}
}
//学生比较器
class CompaByStu implements Comparator<Student>{
@Override
public int compare(Student p1, Student p2) {
int temp;
temp = p1.getAge()-p2.getAge(); //按照年龄比,若相等,按照名字比。
return temp==0?p1.getName().compareTo(p2.getName()):temp;
}
}
说明:一般而言,extend(向下找)用于存储数据,比如人类的容器,学生和工人都可以向里面存储;super(向上找)一般用于取出数据,比如学生数据只能用学生比较器和人类比较器取出。
个人理解:泛型既具有广泛的概念,也具有具体的概念。可以将各种类型进行广泛化,比如泛型类、泛型方法等,但是有时也要具体化,比如在集合中明确要存储什么类型的对象。总之,广泛和具体是相对的,如果出现广泛了,那么在使用的时候,肯定要具体的。