泛型:JDK1.5版本以后出现新特性。用于解决安全问题,是一个安全机制。
像数组一样,提前定义存放类型,解决安全隐患。
ArrayList<String> al = new ArrayList<String>();
定义一个ArrayList容器,存放String类型。
好处:
1、将运行时期出现问题ClassCastException,转移到了编译时期。
方便于程序员解决问题。让运行事情问题减少。
2、避免了强制转换的麻烦。
泛型格式:通过<>来定义要操作的引用数据类型。
在使用java提供的对线时,什么时候写泛型?
通常在集合框架中很常见。
只要见到<>就要定义泛型。
例如:
接口 Collection<E> E 代表元素。 Element。
其实<>就是用来接收类型的。
当使用集合时,将集合中要存储的数据类型作为参数传递到<>中即可。
Comparator<T> T代表对象类型。
什么时候定义泛型类?
当类中要操作的引用数据类型不确定的时候,(基本数据类型不能这样用)
早期定义Object来完成扩展。
现在定义泛型来完成扩展。
//没有泛型前的做法
class Tool
{
private Object obj;
public void setObject(Object obj)
{
this.obj=obj;
}
public Object getObject()
{
return obj;
}
}
//有泛型后的做法
class Utils<QQ>
{
private QQ q;
public void setObject(QQ q)
{
this.q = q;
}
public QQ getObject()
{
return q;
}
}
//<strong>泛型类定义的泛型,在整个类中有效</strong>。如果被方法使用。
//那么泛型类的对象明确要操作的具体类型后,所有要操作的类型就已经固定了。
//为了让不同方法可以操作不同类型,而且类型还不确定。
//那么可以将泛型定义在方法上。
class Demo2
{
public <T> void show(T t)
{
System.out.println("show:"+t);
}
public <Q> void print(Q t) //Q也可以写成T 局部有效
{
System.out.println("print:"+t);
}
}
//一个定义了泛型的类中,可以存在泛型方法。
//特殊之处:
//<strong>静态方法不可以访问类上定义的泛型。</strong>
//如果静态方法操作的应用数据类型不确定,可以将泛型定义在方法上。
/*
* public static <W> void method(W t)//泛型定义只能放在返回类型的前面。放在其他地方会出现错误。
* {
* System.out.println("method:"+t);
* }
*/
//泛型定义在接口上
interface Inter<T>
{
void show(T t);
}
//类型的数据类型确定。
class InterIm implements Inter<String>
{
public void show(String t)
{
System.out.println("show :"+t);
}
}
//类型的数据类型不确定。
class InterImpl<T> implements Inter<T>
{
public void show(T t)
{
System.out.println("show:"+t);
}
}
//泛型高级应用:
import java.util.ArrayList;
import java.util.Iterator;
public class GeneriDemo6 {
public static void main(String[] args)
{
ArrayList<String> al = new ArrayList<String>();
al.add("abc1");
al.add("abc2");
al.add("abc3");
ArrayList<Integer> all = new ArrayList<Integer>();
all.add(4);
all.add(5);
all.add(6);
printColl(al);
printColl(all);
}
/*
public static <T> void printColl(ArrayList<T> al)
{
Iterator<T> it = al.iterator();
while(it.hasNext())
{
//T t = it.next();//只有泛型中不为?时才可以。
System.out.println(it.next());
}
}
*/
public static void printColl(ArrayList<?> al)//?为占位符,表示不明确的类型。
{
Iterator<?> it = al.iterator();
while(it.hasNext())
System.out.println(it.next()); //不能使用特有的方法。如it.next().toString();
}
}
ArrayList<Student> al = new ArrayList<Person>(); 错误。
泛型限定:
<? extends Person>
可以使用Person与Person的子类。
? 通配符。也可以理解为占位符。
泛型的限定:
? extends E : 可以接收E类型和E的子类型。上限限定。
举例:
Collection<? extends Person>
public static void printColl(Collection<? extends Person> al)
{
Iterator<? extends Person> it = al.iterator();
while(it.hasNext())
System.out.println(it.next().getName());
}
? super E : 可以接收E类型或者E的父类型。下限限定。?代表父类型。
举例:
TreeSet(Comparator<? super E> comparator)
现在有:
Person
|--Student
|--Worker
Student和Worker是Person的子类,TreeSet(Person)
当要程序中有Stedent和Worker时,Compareator的指定泛型为<Person>。
Stedent和Worker就都可以用这个比较器。