泛型用来定义使用未知数据类型作为参数的方法和接口是非常好用,但是既然是泛型,就代表可接收的数据类型是任意的,没有严格要求,但是如果需要给泛型的类型给出明确的范围,又应该怎么操作呢?此时就应当为泛型设定限制——受限泛型,可以指定一个泛型的上限和下限。
泛型的上限:
- 格式:类型名称 <? extends E> 对象名称
- 意义:只能接收E类本身及其子类
泛型的下限:
- 格式:类型名称 <? super E> 对象名称
- 意义:只能接收E类型本身及其父类型
比如:现已知Object类,String类,Number类,Integer类,其中Number是Integer的父类
举个例子:
public static void main(String[] args){
/*
类与类之间的继承关系
Integer extends Number
Numebr extends Object
String extends Object
*/
Collection<Integer> list1 = new ArrayList<Integer>();
Collection<String> list2 = new ArrayList<String>();
Collection<Number> list3 = new ArrayList<Number>();
Collection<Object> list4 = new ArrayList<Object>();
getElement1(list1);
getElement1(list2);//报错
getElement1(list3);
getElement1(list4);//报错
getElement2(list1);//报错
getElement2(list2);//报错
getElement2(list3);
getElement2(list4);
}
//泛型上限,调用该方法的参数必须是Number类型或者其 “子” 类型
public static void getElement1(Collection<? extends Number> s){}
//泛型下限,调用该方法的参数必须是Number类型或者其 “父” 类型
public static void getElement2(Collection<? super Number> s){}
其中报错为:
因为分析上方代码可以知道,getEle1
方法在接受list2
、list4
与getEle2
方法接收list1
、list2
时,参数超过了方法中规定的数据类型的范围,因此会报错。String
与Object
都不是Number
的子类,于Number
也没有父子继承关系。Integer
与String
都不是Number
的父类,故不在受限泛型内(上图为idea界面,红线部分为错误提示)。
日常开发中受限泛型不太常用,能做到拿到源码可以看懂其所表达的受限泛型的范围就可以了。