本文索引:
一 泛型简介
二接口的泛型和实现它的类的关系
三接口和所带泛型的关系
四 泛型方法的参数问题
五 独立于类的泛型方法的报错和解决
六 泛型中的重要类型,如:? super Person(或? extends Person)
七总结
一 泛型简介
java的泛型机制是jdk1.5后出现的一种安全机制。它是通过把运行时期可能存在的强制转换中出现的ClassClastException(类型转换异常)转到了编译时期,让程序员在编译时期发现并修改,避免出现不安全问题。所以它主要的功能就是,限制类型。另外有关泛型的补偿机制朋友们也可以去了解一下,这里不作介绍。
二 接口的泛型和实现它的类的关系一个类实现了一个带有泛型的接口,便有了一些新功能。而如果那个接口里有一部分功能对实现它的类有针对性(或者说这个接口就是为了该类定义的)那么它们之间就有关系。
比如我们可以怎么定义:
//这个接口可以实现比较功能,它所比较的对象和实现它的类相同。
interface Comparable<E>{
public boolean CompareTo(E e){}
}
//实现该接口
class Person implements Comparable<Person>{
public boolean CompareTo(Person p){
//代码
}
}
另外一个例子:
集合TreeSet<E>它有一个方法:boolean add(E e) ,该方法可以添加对象(并按二叉树的性质给所添加对象进行排序)
我们没有学泛型之前这么使用它:
TreeSet ts = new TreeSet();
实际上面的代码等于:
TreeSet<Object> ts = new TreeSet<Object>(); 或TreeSet<?> ts = new TreeSet<?>();
所以此时没有写泛型就默认是Ojbect类型,而且add可以添加任意对象。
但是如果指定了泛型,那就只可以添加所指定的泛型的对象,比如:
TreeSet<Person> ts = new TreeSet<Person>();
那么ts就只可以添加Person对象因为方法add方法变成add(Person p)。
所以ts和Person建立了关系。
三接口和所带泛型的关系
就像第二点所说的:泛型接口和所实现它的类的关系外。另外一种关系是:泛型接口和实现它的类没有关系,但是和接口本身所带的泛型有关系,此时让这个类实现它只是为了new出类具备接口方法的对象。简单说:接口和类没有关系和接口所带泛型有关系。
比如:
//比较器
import java.util.Comparator;
public class ComparatorByName implements Comparator<Person>{
//按Person的属性姓名优先,年龄次之的排序
public int compare(Person p1 , Person p2){
int temp = p1.getName().compareTo(p2.getName());
return temp == 0? p1.getAge() - p2.getAge():temp;
}
}
比较器实现了Comparator接口,目的不是想比较两个比较器对象(这里说接口的泛型和
实现它的类没有关系是因为实现接口不是象上面的第一个Person例子一样比较两个实现类本身的对象)。而是实现了Person对象比较的方法,把这种方法封装在一个类里。作用于Person对象。我把他叫做泛型接口和实现它的类没有关系可是和接口定义的泛型(Person对象)有关系。
怎么作用于Person呢?如下:
TreeSet<Person> ts = new TreeSet<Person>(new ComparetorByName());
四泛型方法的参数问题
泛型方法的参数有多少种类型呢,如下:
import java.util.Collection;
//自定义一个泛型类
class MyCollection<E>{
E e;
//方法参数非本类类型
public void method1(Collection<?> coll){}
publilc void methid2(Collection<E> coll){}//和类的泛型一样不需重复在方法上声明
public void method3(Collection<String> cool){}//String Integer 等不需声明在返回值前,访问修饰符后,会默认帮你声明。
//方法参数中的元素是本来体系
public void methid4(Collection<? extends E> cool){}
public void method5(Collection<? super E> cool){}
//方法参数为本类
public void method6(E e){} //和类的泛型一样不需重复在方法上声明
}
}
五 独立于类的泛型方法的报错和解决
有些方法的方法参数和定义类时类的泛型不一样,并且方法里的操作和类的泛型没有关系。
那么我们可以认为该方法独立于它所在类,它们定义泛型和用泛型参数在方法上完成。这种方法分静态和非静态(如果有返回值那么把void改成泛型,当然下面代码的T可以改为Q什么的,只是一个标记)。如下几种形式等等:
class MyCollection<E>{
//一下方法不是String Integer(包装类类型)等等 并且和类的泛型不一样所以要在方法上声明,不能直接使用!
public <T> void method1(T t){}
public static <T> void method2(T t){}
//public static void method(E e){} 这个是错误的静态方法不可以和类的泛型一样
//这里的<T>是声明小括号里面的是使用
}
六 泛型中的重要类型,如:? super Person(或? extends Person)
关于这两句代码,我这里不用代码简单介绍一下,这里的Person是一个类。
? super Person代表Person的父类。
? extends Person 代表Person的子类。
详细的就请等下以后的博文了。
七 总结
从3天前开始学泛型,一开始好乱,然后看懂泛型代表什么,接着又不明白它的设计(它的设计或是设计泛型类什么的是我感觉最难的),现在要好好体会它的设计模式。
这篇算是我学泛型的一个阶段性总结,个人水平所限错误之处难免,大家批评指正。
也把它分享给大家,希望共同进步!