---------------------- ASP.Net+Android+IOS开发、.Net培训、期待与您交流! ----------------------
泛型:JDK1.5版本以后出现新特性,用于解决安全问题,是一个安全机制
格式:通过<>来定义要操作的引用数据类型集合<参数类型> ,该参数类型不可以用基本数据类型(int char等),只有用引用数据类型,如String,Integer,数组等
如:ArrayList<String> al = new ArrayList<String>();
Iterator<String> it = al.iterator();
好处:
1.将运行时期出现问题ClassCastException,转移到了编译时期,方便于程序员解决问题,让运行时期问题减少
2.避免了强制转换的麻烦
在使用Java提供的对象时,什么时候写泛型呢?
通常在集合框架中很常见
只要见到<>就要定义泛型 API中会有写明,比如ArrayList<E>
<>就是用来接收类型的
当使用集合时,将集合中要存储的数据类型作为参数传递到<>中即可
示例:
import java.util.*;
class TreeSetStringTest
{
public static void main(String[] args)
{
TreeSet<String> ts = new TreeSet<String>(new Comparator<String>(){
public int compare(String str1, String str2) //因为Comparator接口支持泛型,所以覆盖可以这样写
{
if (!(str1 instanceof String) || !(str2 instanceof String))
throw new RuntimeException("不是一个字符串");
/*正序
int num = new Integer(str1.length()).compareTo(str2.length());
if (num==0)
return str1.compareTo(str2);
*/
//倒序
int num = new Integer(str2.length()).compareTo(str1.length());
if (num==0)
return str2.compareTo(str1);
return num;
}
});
ts.add("a");
ts.add("abc");
ts.add("bb");
ts.add("aa");
//ts.add(4); //4自动装箱为new Integer(4); 因为定义了泛型<String>,这个是整型,所以编译时就会出现错
for (Iterator<String> it = ts.iterator(); it.hasNext(); ) //因为Iterator定义了泛型<String>
{
String s = it.next(); //所以这里不用强制转换
sop(s);
}
}
public static void sop(Object obj)
{
System.out.println(obj);
}
}
泛型类
什么时候定义泛型类?
当类中要操作的引用数据类型不确定的时候,早期定义Object来完成扩展(强转),现在可以定义泛型来完成扩展
示例:
class Tools<E>
{
private E e;
public void setObject(E e)
{
this.e = e;
}
public E getObject()
{
return e;
}
}
泛型定义在类上
泛型类定义的泛型,在整个类中有效,如果被方法使用,那么该方法传入的类型已经被类中定义的类型固定了,除非重新创建新类型的类 即 Tools<String> t1 = new Tools<String>(); Tools<Integer> t2 = new Tools<Integer>();
泛型定义在方法上
为了让不同方法可以操作不同类型,而且类型不确定的情况下,可以将泛型定义在方法上
注意:静态方法不可以访问类上定义的泛型,如果静态方法操作的应用数据类型不确定,可以将泛型定义在方法上
原因:静态先加载对象后加载,而泛型类上的参数要等对象建立之后才知道该参数的值是什么,即静态不能访问非静态
泛型定义在接口上
示例
interface Inter<E>
{
void show(E e);
}
class Tools<E> implements Inter<E>
{
public void show(E e)
{
System.out.println("show:"+e);
}
public <Q> void print(Q q)
{
System.out.println("print:"+q);
}
public static <Q> void get(Q q) //此Q和print方法中的Q无关
{
System.out.println("get:"+q);
}
}
class NewDemo
{
public static void main(String[] args)
{
Tools<String> tl = new Tools<String>();
tl.show("abc");
//tl.show(4); Tools类泛型定义的数据类型为String,所以编译出错
tl.print("cde");
tl.print(5);
tl.get(3.5);
}
}
泛型限定
? 通配符,也叫占位符
<? extends Fu> 上限:接收Fu类或Fu类的子类
<? super Zi> 下限:接收Zi类或者Zi类的父类,注意super最上层为Object
注:若使用泛型限制取值,使用方法时,该泛型范围内,都应该具备该方法,否则编译不通过
示例:
import java.util.*;
class Fu
{
private String name;
Fu(String name)
{
this.name = name;
}
public String getName()
{
return name;
}
}
class Zi extends Fu
{
Zi(String name)
{
super(name);
}
}
class Other
{
private String name;
Other(String name)
{
this.name = name;
}
}
class NewDemo
{
public static void main(String[] args)
{
ArrayList<Fu> al = new ArrayList<Fu>();
al.add(new Zi("Fu-Zi1")); //父类容器可以存放子类元素,但不能ArrayList<Fu> al = new ArrayList<Zi>();
al.add(new Zi("Fu-Zi2"));
al.add(new Fu("Fu-1"));
al.add(new Fu("Fu-2"));
ArrayList<Zi> az = new ArrayList<Zi>();
az.add(new Zi("az-1"));
az.add(new Zi("az-2"));
az.add(new Zi("az-3"));
ArrayList<Other> ot = new ArrayList<Other>();
ot.add(new Other("ot-1"));
ot.add(new Other("ot-2"));
ot.add(new Other("ot-3"));
getListDown(al);
getListAny(ot);
getListT(ot);
}
public static void getListDown(ArrayList<? extends Fu> al) //ArrayList泛型只要是Fu类或者Fu类的子类即可传入,即al,az可以传入,ot不可以传入
{
for (Iterator<? extends Fu> it = al.iterator(); it.hasNext(); )
{
System.out.println(it.next().getName()); //因为泛型限制中的Fu,Zi里都有这个方法,所以可以使用
}
}
public static void getListUp(ArrayList<? super Zi> al) //ArrayList泛型只要是Fu类或者Fu类的子类即可传入,即al,az可以传入,ot不可以传入
{
for (Iterator<? super Zi> it = al.iterator(); it.hasNext(); )
{
System.out.println(it.next()); //因为super的最上级是Object,Object中并无getName(),所以无法使用自定义的getName()方法
}
}
public static void getListAny(ArrayList<?> al) //ArrayList泛型随便是什么类型,都可以传入
{
for (Iterator<?> it = al.iterator(); it.hasNext(); )
{
System.out.println(it.next()); //不清楚是什么类型,所以无法使用自定义的getName()方法
}
}
public static <T> void getListT(ArrayList<T> al) //ArrayList泛型为T,it.next()可返回T数据类型
{
for (Iterator<T> it = al.iterator(); it.hasNext(); )
{
T t = it.next(); //不清楚是什么类型,所以无法使用自定义的getName()方法
System.out.println(t);
}
}
}
---------------------- ASP.Net+Android+IOS开发、 .Net培训、期待与您交流! ----------------------详细请查看: http://edu.csdn.net