目录:1、泛型概述 2、泛型使用 3、泛型方法 4、静态方法泛型 5、泛型限定
1、泛型概述:
JDK1.5版本以后出现的新特性,用于解决安全问题,是一个安全机制.
升级有三部分:高效 简化书写 安全
泛型好处
1 将运行时期问题ClassCastException转移到了编译时期,方便于程序员解决问题,让运行时期问题减少
2 避免了强制转换的麻烦
ClassCastException 类型转换异常
import java.util.*;
class GenericDemo
{
public static void main(String[] args)
{
/*
如果想要将数组天添加到集合容器中,运行会出现错误,因为在定义容器的时候已经明确数据类型了
int[] arr = new int[3];
arr[0] = 4;
arr[1] = 3.5;
*/
ArrayList<String> al = new ArrayList<String>();//泛型用<>
al.add("abc01");
al.add("abc0991");
al.add("abc014");
//al.add(4);//add(new Integer(3))JDK1.5版本以后可以添加数字,数字有自动拆箱,自动装箱
Iterator<String> it = al.iterator();
while(it.hasNext())
{
//想要打印字符串的长度,所以要强转
String s = it.next();
System.out.println(s+":"+s.length());
}
}
}
2、泛型使用
泛型格式: 通过<>来定义要操作的引用数据类型
通常在集合框架中很常见,只要见到<>就要定义泛型
其实<>就是用来接收类型的
当使用集合时,将集合中要存储的数据类型作为参数传递到<>中即可
import java.util.*;
class GenericDemo2
{
TreeSet<String> ts = new TreeSet<String>();
ts.add("abcd");
ts.add("cc");
ts.add("cbz");
ts.add("haha");
Iterator<String> it = ts.iterator();
while(it.hasNext())
{
String s = it.next();
System.out.println(s );
}
}
3、泛型方法
当泛型定义在方法上时,要放在修饰符的后面,返回值类型的前面.
泛型不但可以定义在类上,也可以定义在方法上
泛型类的局限性,当泛型类型确定后,所要传进的类型都必须一致
泛型类在定义的泛型在整个类中有效,如果被方法使用,那么泛型类的对象明确要操作的具体类型后,所有方法要操作的类型都已经固定了
为了让不同方法,操作不同类型,而且类型还不确定,那么可以将泛型定义在方法上
class Demo
{
//把泛型定义在方法上
public <T> void show(T t)
{
System.out.println("show:"t);
}
public <Q> void print(Q t)
{
System.out.println("print:"+q);
}
}
class GenericDemo4
{
public static void main(String[] args)
{
Demo d = new Demo();
d.show(new Integer(3));
d.print("haha ");
//Demo<String> d = new Demo<String>();
//t.show("haha");
//t.print("hehe");
}
}
4、静态方法泛型
静态方法不可以访问类上定义的泛型,如果静态方法操作的引用数据类型不确定,可以将泛型定义在方法上
方法先加载静态,泛型后加载
5、泛型限定
?: 可以理解为通配符,也可以理解为占位符
当泛型的数据类型不确定时,可以用通配符<?>
多态不能预先使用子类中的方法
<? extend E>: 可以接受E类型或者E类的子类型,这儿叫做上限限定
<? super E> : 可以接受E类型或者E类型的父类型.这儿叫做下限限定
ArrayList<Person> al = new ArrayList<Person>();
al.add(new Person("abc1"));
al.add(new Person("abc2"));
al.add(new Person("abc3"));
printColl(al);
ArrayList<Student> al1 = new ArrayList<Student>();
al1.add(new Student("abc4"));
al1.add(new Student("abc5"));
al1.add(new Student("abc6"));
printColl(al1);//这句话就相当于:ArrayList<Person>al = new ArrayList<Student>();//编译器不允许error
}
public static void printColl(ArrayList<? extends Person> al)//泛型限定后就可以接受Person类型以及子类
{
Iterator<? extends Person> it = al.iterator();
while(it.hasNext())
{
System.out.println(it.next().getName());
}
}
泛型限定是用于泛型扩展用的
import java.util.*;
class TreeSetDemo7
{
public static void mian(String[] args)
{
//建立TreeSet集合,里面要存入的是Student类型的对象
TreeSet<Student> ts = new TreeSet<Student>(new Com());//这个位置要把比较器对象扔进去.
ts.add(new Student("lisi"));
ts.add(new Student("zhangsan"));
ts.add(new Student("wangwu"));
TreeSet<Worker> ts = new TreeSet<Worker>(new Com());//这个位置要把比较器对象扔进去.
ts1.add(new Worker("lisiWW"));
ts1.add(new Worker("zhangWW"));
ts1.add(new Worker("wangwWW"));
//然后建立迭代器
Iterator<Student> is = ts.iteratro();
while(it.hasNext())
{
System.out.println(is.next().getName());
}
Iterator<Worker> is = ts1.iteratro();
while(it.hasNext())
{
System.out.println(is.next().getName());
}
}
}
/*
//因为Student对象本身不具备比较特性,所以要建立一个比较器
class StuComp implements Comparator<Student>
{
public int compare(Student s1,Student s2)
{
return s1.getName().compareTo(s2.getName())
}
}
//建立一个Worker比较器
class WorkerComp implements Comparator<Worker>
{
public int compare(Worker w1,Worker w2)
{
return s1.getName().compareTo(s2.getName())
}
}
因为每一次传进来一个对象,都要创建一个比较器,比较麻烦
*/
class Com implements Comparator<Person>
{
public int compare(Person p1,Person p2)
{
return p2.getName().compareTo(p1.getName());
}
}
class Worker extends Person
{
Worker(String name)
{
super(name);
}
}