java泛型的上界下界的demo。
import java.sql.Timestamp;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
/**
* 泛型上下界
*/
public class UpAndDownGeneric {
/**
* 1、上界可以读取成上界类型Date,但是不能存储,因为这个实际类型有可能是子类,而你指定Date不行,Date的下级也不行,依次同理。
*/
public void upperBound(List<? extends Date> list, Date date){
Date now = list.get(0); //这里当然也可以用Object接受。
System.out.println("now==>" + now);
// list.add(date); //这句话无法编译
list.add(null); //这句可以编译,null没有类型信息
}
/**
* 比如下面这个方法,泛型是Timestamp类型,而add的时Date类型。
* 上界读不能存,因为泛型类型可能无限小,任何参数的类型都不能直接使用。
*/
public void testUpperBound(){
List<Timestamp> list = new ArrayList<Timestamp>();
Date date = new Date();
upperBound(list,date);
}
/**
* 解决,声明List泛型为T,在方法定义T为Date子类,那么传递的类型永远符合T的类型了。就可以添加了。
*/
public <T extends Date> void upperBound2(List<T> list, T date){
T now = list.get(0);
System.out.println("now==>" + now);
list.add(date); //这句话无法编译
list.add(null); //这句可以编译,null没有类型信息
}
/**
* 2、下界不能够读,可以写,因为泛型实际类型都大于Timestamp,所以放心的写,而读的话,不知道返回什么类型了。
*/
public void lowerBound(List<? super Date> list){
Date now = new Date(System.currentTimeMillis());
list.add(now);
list.add(new Timestamp(System.currentTimeMillis())); //可以添加比Date小的类型。
//Date time = list.get(0); //需要强转成Object,才能读。
}
/**
* 比如下面这个:list符合泛型限制,但是添加的是一个Object,所以在lowerBound调用时,get要强转成Object.
*/
public void testLowerBound(){
List<Object> list = new ArrayList<>();
list.add(new Object());
lowerBound(list);
}
//一句话总结:
//泛型上界 <? extends 上界类型> 和 泛型下界<? super 下界类型>
//如果是进行读取操作,那么就要能够装的下泛型类型的,即看2种泛型的最大类型,其中上界是上界类型,下界是Object。
//如果时写入操作,那么就要看泛型类型的最小的具体类型及其子类,所以上界不可写,下界可以写入下界类型及子类。
}