-
泛型
学习之初我本来想悄悄跳过这一节。愚蠢。人类真是愚蠢【我指我】。学集合不学泛型可能是背书背多了想把集合章节背下来理解吧。
PS:我现在在看的以及大部分总结内容均来自Cay S.Horstmann著的《Java核心技术卷 1》聪明的朋友萌不要学我 跟着愚蠢的阿柳痛改前非8!
1.简单来说:一个泛型类(generic class)就是具有一个或多个类型变量的类。
例 Pair类:
public class Pair<T>
{
private T first;
private T second;
public Pair(){ first=null; second=null; }
public Pait(T first,T second){ this.first=first; this.second=second; }
public T getFirst(){ return first; }
public T getSecond{ return second; }
public void setFirst(T newValue){ first=newValue; }
public void setSecond(T newValue){ seond=newValue; }
}
注1:泛型类可以有多个类型变量。例如 可以定义Pair类,其中第一个域和第二个域使用不同类型:
public class Pair<T,U>{ . . . }
注2:Java中用E表示集合的元素类型,K和V表示表的关键字(key)和值(value)的类型,T(或者U,S)表示任意类型。
使用泛型类的时候把<>内的T换成所需类型即可。
2.前面介绍了如何定义一个泛型类。下面来定义一个带有类型参数的简单方法。
class ArrayAlg
{
public static <T> T getMiddle(T...a)
{
return a[a.length/2];
}
}
注1:泛型方法既可以定义在普通类中,也可以定义在泛型类中。
注2:类型变量<T>放在修饰符(这里是public static)后,返回类型前。
调用此方法的时候可以:
String middle=ArrayAlg.<String>.getMiddle("Lucy","Bradly',"MengNiu");
注1:大多数情况下可以忽略<>内的类型(连同<>一起去掉),因为编译器可以推断出。比如推断出这里类型是String。
3.类型变量的限定
当我们定义的类或方法中出现了某些特定方法,比如compareTo()。这时候,要确保T所属的类含compareTo()方法。So我们需要对类型变量加以约束。
例:
public static <T extends Comparable>T min(T[] a)...
也可以有多个限定,例:
public static <T extends Comparable&Serializable>T min(T[] a)...
4.约束与局限
(1)不能创建参数化类型的数组,例:
Pair<String>[] table=new Pair<String>[10];//Error
为什么?
因为泛型信息只存在于代码编译阶段,在进入 JVM 之前,与泛型相关的信息会被擦除掉,专业术语叫做类型擦除。只留下它的原始类型(如:Object)。
而数组擦除之后会记住它的元素类型,如果试图储存其他类型的元素,就会抛出ArrayStoreException异常。
(2)不能抛出或捕获泛型类的实例,事实上,甚至泛型类扩展Exception都是不合法的。例:
public class Problem<T> extends Exception {...}//Error:cannot extends Throwable
catch子句中同样也不能使用类型变量,例:
public static <T extends Throwable> void doWork(Class<T> t)
{
try
{
*do work*
}
catch(T e)//Error:cannot catch type variable
{
Logger.global.info(...)
}
}
不过,在异常规范中使用类型变量是允许的,例:
public static <T extends Throwable> void doWork(T t) throws T//OK
{
try
{
*do work*
}
catch(Throwable realCause)
{
t.initCause(realCause);
throw t;
}
}
5.泛型类型的继承规则
考虑一个类和一个子类,如 Employee类和Manager类。Pair《Manager>是Pair《Employee>的一个子类吗?
不是。
无论S类和T类有什么关系,通常Pair《S>和Pair《T>没有什么联系。
6.通配符 ‘?’
啊 不想写了。自行百度。简单来说就是让父子类在泛型中有用武之地了。