泛型是JDK1.5以后出现的新特性,用于解决安全问题,是一个安全机制。
1,泛型的特点:
①将运行时期出现的问题如ClassCaseException转移到编译时期,方便程序员解决问题,让运行时期的问题减少;
①将运行时期出现的问题如ClassCaseException转移到编译时期,方便程序员解决问题,让运行时期的问题减少;
②避免了强制类型转换的麻烦;
2,泛型的使用:
①通常在集合框架中很常见,只要见到<>就需要定义。
②当类中要操作的引用数据类型不确定的时候,早期通过定义Object类来完成扩展,现在通过定义泛型来完成扩展;
泛型在集合中的使用:
import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;
public class GenericDemo {
public static void main(String[] args) {
TreeSet<String> ts = new TreeSet<String>(new LenComparator());//在这个集合中只能存放String类型的对象,否则编译会报错。
ts.add("ax");
ts.add("b");
ts.add("dfko");
ts.add("dfili");
ts.add("d");
Iterator<String> it = ts.iterator();
while(it.hasNext()){
String s = it.next();
System.out.println(s);
}
}
}
class LenComparator implements Comparator<String>{
@Override
public int compare(String o1, String o2) {
int num = new Integer(o2.length()).compareTo(new Integer(o1.length()));
if(num==0){
return o2.compareTo(o1);
}
return num;
}
}
3,自定义的泛型类:
/*泛型类定义的泛型,在整个类中有效,如果被方法使用,那么泛型类的对象明确要操作的具体类型后,所有要操作的类型也就确定了*/
class Worker{
}
class Util<T>{
private T t;
public void setObjet(T t){
this.t = t;
}
public T getObject(){
return t;
}
}
public class GenericDemo1 {
public static void main(String[] args) {
Util<Worker> u = new Util<Worker>();
u.setObjet(new Worker());
Worker w = u.getObject();
}
}
4,自定义的泛型方法:
注意:静态方法不可以访问类上定义的泛型,如果静态方法操作的数据类型不确定个,可以将泛型定义在方法上.
例如:public static <T> void show(T t){ }
/*
* 定义泛型方法
*
* 泛型类定义的泛型,在整个类中有效,如果被方法使用,那么泛型类对象
* 明确要操作的具体类型后,所有要操作的类型就已经固定了。
*
* 为了让不同方法可以操作不同类型,而且类型不确定,
* 可以将泛型定义在方法上。
* */
class Demo<T>{
public void show(T t){
System.out.println("show:"+t);
}
public <Q> void print(Q q){
System.out.println("print::"+q);
}
}
public class GenericDemo2 {
public static void main(String[] args) {
Demo<String> d = new Demo<String>();
d.show("abc");//d.show()只能接收String类型的对象
d.print(3);//d.print()可以接收任意新类型的对象。
d.print("xyz");
}
}
5,泛型在接口上的使用方式:
/*泛型定义在接口上*/
interface Inter<T>{
void show(T t);
}
//实现这个接口的方法一:在实现接口的同时制定泛型的类型。
class InterImpl implements Inter<String>{
public void show(String s){
System.out.println("show..."+s);
}
}
//现象接口的方法二:在实现接口的同时不确定这个类要使用什么类型。
class InterImpl1<T> implements Inter<T>{
public void show(T t){
System.out.println("show...."+t);
}
}
public class GenericDemo3 {
public static void main(String[] args) {
//第一种创建类的方式:
InterImpl i = new InterImpl();
i.show("方式一");
//i.show(8);// 错误的,在定义类的时候就一定确定的类型。只能使用String类型。
//第二种创建方式:
InterImpl1<Integer> i1 = new InterImpl1<Integer>();//可以根据需求,想使用什么样的类型就定义什么样的类型
i1.show(8);
}
}
6,泛型的限定
?表示通配符,也可以理解为占位符
? extends E :表示可以接收E类型或者E类型的子类类型,称为上限;
? super E:表示可以接收E类型或者E类型的父类类型,称为下限;
?通配符的使用:
import java.util.ArrayList;
import java.util.Iterator;
public class Demo1 {
public static void main(String[] args) {
ArrayList<String> al = new ArrayList<String>();
al.add("abc1");
al.add("abc2");
al.add("abc3");
ArrayList<Integer> al1 = new ArrayList<Integer>();
al1.add(3);
al1.add(4);
al1.add(9);
printColl(al1);
printColl(al);
}
public static void printColl(ArrayList<?> al){//当泛型类型不确定的时候可以用?表示,?通配符也可以理解为占位符
Iterator<?> it = al.iterator();
while(it.hasNext()){
System.out.println(it.next());
//System.out.println(it.next().length());//错误的,不能使用子类的特有方法。
}
}
}
? extends E 的使用:
import java.util.ArrayList;
import java.util.Iterator;
public class GenericDemo4 {
public static void main(String[] args) {
ArrayList<Personn> al = new ArrayList<Personn>();
al.add(new Personn("zhangsan"));
al.add(new Personn("lisi"));
al.add(new Personn("wangwu"));
printColl(al);
ArrayList<Studentt> al1 = new ArrayList<Studentt>();
al1.add(new Studentt("zhangsan---"));
al1.add(new Studentt("lisi---"));
al1.add(new Studentt("wangwu---"));
printColl(al1);
}
public static void printColl(ArrayList<? extends Personn> al){//可以接受Personn类以及Personn的子类
Iterator<? extends Personn> it = al.iterator();
while(it.hasNext()){
System.out.println(it.next().getName());
}
}
}
class Personn{
private String name ;
Personn(String name){
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
class Studentt extends Personn{
Studentt(String name) {
super(name);
}
}
? super E 的使用:
因为
TreeSet集合中的比较器支持? super E类型,也就是说可以传一个某个类型或者某个类型的父类。
import java.util.Comparator;
import java.util.Iterator;
import java.util.TreeSet;
/*
* ? super E 的使用
* */
public class GenericDemo5 {
public static void main(String[] args) {
/**/TreeSet<Studentt1> ts = new TreeSet<Studentt1>(new Comp());
ts.add(new Studentt1("zhangsan"));
ts.add(new Studentt1("lis"));
ts.add(new Studentt1("wangwu"));
ts.add(new Studentt1("zhaoli"));
Iterator<Studentt1> it = ts.iterator();
while(it.hasNext()){
System.out.println(it.next().getName());
}
TreeSet<Workers> ts1 = new TreeSet<Workers>(new Comp());
ts1.add(new Workers("zhangsan--------"));
ts1.add(new Workers("lis----------"));
ts1.add(new Workers("wangwu--------"));
ts1.add(new Workers("zhaoli-------"));
Iterator<Workers> it1 = ts1.iterator();
while(it1.hasNext()){
System.out.println(it1.next().getName());
}
}
}
class Comp implements Comparator<Personn1>{//Comparator支持?super E,可以传入Student或者Student的父类Personn1
public int compare(Personn1 o1, Personn1 o2) {
return o2.getName().compareTo(o1.getName());
}
}
class Personn1{
private String name ;
Personn1(String name){
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
class Studentt1 extends Personn1{
Studentt1(String name) {
super(name);
}
}
class Workers extends Personn1{
Workers(String name){
super(name);
}
}