虽然我在泛型的使用这块,应用的地方不是很多,但是还是要总结一下的,这一篇文章主要是从使用的角度,对泛型进行介绍。
如果一个类有一个或者多个类型的变量,那么这个类就是泛型类,这些类型变量是类的类型参数。下边这个类是一个简单的java类,有一个属性t,它的类型是Object
方法上的泛型
class DemoClass {
private Object t;
public void set(Object t) { this.t = t; }
public Object get() { return t; }
}
这里它可以存入任何类型的数据,没有任何限制,如果要对它的类型进行限制怎么办呢?我们可以进行如下的使用
class DemoClass<T> {
//T stands for "Type"
private T t;
public void set(T t) { this.t = t; }
public T get() { return t; }
}
那么调用的时候就会有下边的结果:
DemoClass<String> instance = new DemoClass<String>();
instance.set("lokesh"); //正确的用法
instance.set(1); //编译错误
接口上的泛型
我们看下边这个例子就能快速的理解
// 泛型接口的定义
interface DemoInterface<T1, T2>
{
T2 doSomeOperation(T1 t);
T1 doReverseOperation(T2 t);
}
//实现泛型接口的类
class DemoClass implements DemoInterface<String, Integer>
{
public Integer doSomeOperation(String t)
{
//其他代码
}
public String doReverseOperation(Integer t)
{
//其他代码
}
}
方法上的泛型
方法上的泛型和类上的泛型很像,唯一不同的是类型的作用域不同。下边这段使用泛型方法的代码用来找出类型相同参数的个数
public static <T> int countAllOccurrences(T[] list, T item) {
int count = 0;
if (item == null) {
for ( T listItem : list )
if (listItem == null)
count++;
}
else {
for ( T listItem : list )
if (item.equals(listItem))
count++;
}
return count;
}
如果你是传递的String的列表,和另一个String,可以正常运行,但是如果你在这个String List中找Number则会出现变异错误。
构造方法上的泛型
class Dimension<T>
{
private T length;
private T width;
private T height;
//泛型构造方法
public Dimension(T length, T width, T height)
{
super();
this.length = length;
this.width = width;
this.height = height;
}
}
使用通配符的泛型
通配使用“?”作为标记,代表未知的类型
Collection<?> coll = new ArrayList<String>();
//可以通配所有的类型
List<? extends Number> list = new ArrayList<Long>();
//通配Number子类的类型
Pair<String,?> pair = new Pair<String,Integer>();
//String和其它类型
下边的代码会出错
List<? extends Number> list = new ArrayList<String>();
//String 不是Number的子类,所以会出错
Comparator<? super String> cmp = new RuleBasedCollator(new Integer(100));
//String 不是Integer的超类
不允许使用泛型的地方
a) 不能是静态的类型
public class GenericsExample<T>
{
private static T member; //This is not allowed
}
b)不能创建T的实例
public class GenericsExample<T>
{
public GenericsExample(){
new T();
}
}
c)在声明时不能和原生类型一起使用
final List<int> ids = new ArrayList<>(); //不允许
final List<Integer> ids = new ArrayList<>(); //允许
d) 不能创建泛型的异常类
// 引起编译错误
public class GenericException<T> extends Exception {}
关注我,获取400个的赚钱金点子,轻松开启副业生涯