泛型是将数据类型参数化以达到代码复用提高程序开发效率的一种特性。java泛型的提出是针对List集合存入对象时不会记忆数据类型,再次取出对象时就变成object类型而提出的一种解决方式。因此泛型的应用在底层代码封装中广泛使用。
自java 5以后,java引入参数化类型概念,使用泛型,例如:List<String>,表明该集合只能存储String对象。
先看一下泛型类的定义:
public class Apple<T>
{
private T info;
public Apple(){
}
public Apple(T info){
this.info=info;
}
public void setInfo(T info){
this.info=info;
}
public T getInfo{
return this.info;
}
public static void main(String[] args){
Apple<String>a1=new Apple<>("苹果");//泛型的菱形定义
System.out.println(a1.getInfo());
Apple<Double>a2=new Apple<>(5.66);
System.out.println(a2.getInfo());
}
}
(1)泛型的继承必须要明确指明存储的数据类型,且泛型集合类不能使用静态方法,例如:
public class A1 extends Apple<String>{...}
如果上面的apple改成Apple<T>则编译时是无法通过的。
(2)泛型的“父类”可以通过通配符来表示,通常用作限定通配符,例如:
public abstract class Person{
public abstract void work();
}
public class man extends Person{
public void work(){
System.out.println("男人的工作");
}
}
public class womman extends Person{
public void work(){
System.out.println("女人的工作");
}
}
public class PepoleWork{
public void doWork(List<? extends Person> persons){ //限定通配符只能是person,在方法类中定义具体的类
for(object obj :persons){
Person p=(Person)(obj);
p.work();
}
}
}
当需要限定多个参数类型时则可以通过&进行连接:
public class Apple<T Number & java.io.Serializable>
{
...;
}
(3)泛型方法:
//将指定的数组转化为集合
static <T> void formArrayToCollection(T[]a,Collection<T> c){
for(T o:a){
c.add(o);
}
}
public static void main(String[] args){
Object[] oa=new Object[100];
Collection<object> co=new ArrayList<>();
formArrayToCollection(oa,co);
String[] sa=new String[100];
Collection<String> cs=new ArrayList<>();
formArrayToCollection(sa,cs);
}
如上面的实例,将数组转化为集合,泛型方法定义时在返回类型前面多了一个类型参数。该方法可以将多种类型的数组转化为集合。
当两个转化参数不一致时必须有参数继承关系,如下实例:
public class RightTest
{
static <T> void test(Collection<? extends T>form,Collection<T> to){
for(T ele:form){
to.add(ele);
}
}
public static <T> T copy(Collection<? super T> dest,Collection<T> src){
T last=null;
for(T ele:src){
last=ele;
dest.add(ele);
}
return last;
}
public static void main(String[] args){
List<object> ao=new ArrayList<>();
List<String> as=new ArrayList<>();
//String类型集合转化为Object类型集合
test(as,ao);
}
}
(4)泛型集合与通配符的关系
一般情况下通配符均可以转化为泛型方法,例如:
public interface Collection<E>
{
boolean containsAll(Collection<?> c);
boolean addAll(Collection<? extends E>c);
}
/*类型形参T只使用一次,则应该使用通配符:支持灵活的子类化*/
public interface Collection<E>{
<T> boolean containsAll(Collection<T> c);
<T extends E>boolean addAll(Collection<T> c);
}
当类型参数只使用一次时,应该使用通配符:支持灵活的子类化;一个类型参数a或者返回值类型依赖于另一个形参b的类型,则考虑泛型方法,例如java里面Collections类的copy()方法:
public class Collections{
public static<T>void copy(List<T> dest,List<? extends T> src){...};
}