一直有用到泛型,可是没有深刻研究其用法,今天遇到一个方法就有点蒙圈,以下:java
public <T extends TransactionBaseService> int aroundTransHelper(T service, Map<String, Object> params, Map<String, Object> container) throws Exception {
return 0;app
}ide
后来理解为<T extends TransactionBaseService>是定义后面的泛型参数(若理解错了,再来改正).ui
详细的定义和引用见:http://my.oschina.net/jiemachina/blog/201507.net
还有看到的一篇不错的blog引用以下:对象
泛型机制经常使用的参数有3个:
“?”表明任意类型。若是只指定了<?>,而没有extends,则默认是容许任意类。
extends关键字声明了类型的上界,表示参数化的类型多是所指定的类型,或者是此类型的子类。
super关键字声明了类型的下界,表示参数化的类型多是所指定的类型,或者是此类型的父类型,直至Object
前提
Fruit是Apple和Orange的超类。
本章经过java代码逐一分析泛型参数的意义和区别
extends参数:
[java]
public void extend(List<? extends Fruit> list, Fruit fruit){
Fruit now = list.get(0);
System.out.println("now==>" + now);
// Apple a = list.get(0); 没法经过编译
Object o = list.get(0);
System.out.println(o);
// list.add(fruit); //这句话没法编译
// list.add(new Object()); // 没法经过编译
list.add(null);//这句能够编译,由于null没有类型信息
}
在上面的例子中,能够明确从list中取得的记录必定是Fruit,可是没法肯定是Apple,list除了传入null外,不能添加其余任何参数;分析缘由前先看如下的例子:
[java]
public void testExtendType(){
List<? extends Fruit> list = new ArrayList<Fruit>();
List<? extends Fruit> list2 = new ArrayList<Apple>();
List<? extends Fruit> list3 = new ArrayList<Orange>();
extend(list2, new Apple());
}
从以上代码能够看出:
extends关键字声明了类型的上界,表示参数化的类型多是所指定的类型,或者是此类型的子类,List<? extends Fruit> 能够指向 ArrayList<Fruit>()、ArrayList<Apple>()、ArrayList<Orange>()等。如今若是传入的参数list为new ArrayList<Apple>(),则此时你向此list中添加
Fruit,则确定报错。而读取数据时,无论list是什么类型,读取的数据确定都是Fruit,同时Fruit也是Object。
经过以上的分析,知道直接往继承extends中的列表中添加记录是不行的,那么如何向extends修饰的list中添加记录,可使用泛型方法来达到目的:
[java]
public <T extends Fruit> void extendType2(List<T> list, T date){
list.add(date);
}
调用示例以下:
[java]
public void testExtendType2(){
List<Apple> list = new ArrayList<Apple>();
extendType2(list,new Apple());
}
super参数
super用的很少,只简单介绍一下。
[java]
public void superType(List<? super Apple> list, Apple apple){
Object o = list.get(0);
System.out.println(o);
// Apple a = list.get(0); // 不能编译
// Apple apple = list.get(0); // 不能编译
list.add(apple);
// list.add( new Object()); // 不能编译
// list.add( new Fruit()); // 不能编译
}
在以上代码中,从list中读取的记录没法肯定是任何类型(除Object),list除了添加Apple外,不能添加任何类型的对象(包括Object)。分析缘由前先看如下代码:
[java]
public void testSuperType(){
List<? super Apple> list = new ArrayList<Apple>();
List<? super Apple> list2 = new ArrayList<Fruit>();
superType(list2, new Apple());
}
super关键字声明了类型的下界,表示参数化的类型是所指定的类型,或者是此类型的父类型,直至Object。List<? super Apple > 能够引用 List<Apple>,也能够引用 List<Fruit>,因此没法保证list中都是Apple,可是能够保证,全部list引用的都是Apple的父类,全部向此列表中添加Apple是没有问题的,而很显然你向List<Fruit>、List<Apple>中添加Object、Fruit对象,确定失败,只可以添加Apple。
?参数
“?”表明任意类型。?能够看作 ? extends Object 的缩写。
[java]
public void wideCardType(List<?> list, Fruit fruit ){
Object o = list.get(0);
System.out.println(list.get(0));
// list.add(fruit); // 不能编译
// list.add(new Object()); // 不能被编译
}
[java]
public void testWideCardType(){
/**
* ? 能够看作 ? extends Object 的简化版
*/
List<?> list = new ArrayList<Fruit>();
List<?> list2 = new ArrayList<Apple>();
List<?> list3 = new ArrayList<Object>();
wideCardType(list,new Fruit());
}
List<? super Object> 能够引用 List<任何类型>,而Object是全部的对象的祖先,此list只能添加Object类型对象。
extends和super意义记忆的技巧
? extends A: ?继承A,?是A的子类,或者?是A自己
? super B: ?是B的父类,或者?是B自己blog