泛型的高级用法包括限制泛型可用类型和使用类型通配符
类型通配符
通配符:?–>表示类型不确定,用于申明变量或者形参上,只能用在声明类型 、方法参数上,不能用在定义泛型类上,其主要作用是在创建一个泛型类对象时限制这个泛型类的类型实现或继承某个接口或类的子类。
public class TestWildcard {
public static void main(String[] args) {
//声明
List<?> list =new ArrayList<Integer>();
list =new ArrayList<String>();
list =new ArrayList<Object>();
/**list =new ArrayList<?>();
*编译错误 不能创建对象 */
test(list);
}
//可用于泛型方法声明
public static void test(List<?> list){
}
/**不能用于泛型方法声明的返回值
public static <?> void test2(List<?> list){
}
*/
class Test<T>{
}
/**不能用在创建泛型类
class Test2<?>{
}
*/
}
限制泛型可用类型
限制泛型可用类型用来对泛型类的实例的类型做了限制,主要包括两个:
extends–>表示<=,也就是上限,指定的类型必须是继承某个类,或者实现某个接口
super–>表示>= ,也就是下限,指定的类型不能小于操作的类
下面通过实例来解释:
先定义一个水果类:
package genericity_wildcard;
/**
* 继承链
* Object
* |
* Fruit
* / \
* Apple Pear
* |
* FujiApple
*/
public class Fruit {
}
class Apple extends Fruit{
}
class Pear extends Fruit{
}
class FujiApple extends Apple{
}
import java.util.ArrayList;
import java.util.List;
/**
* extends : 泛型的上限 <= 即子类或自身
* 1、一般用于上限操作
* 2、不能使用在添加数据上面,一般都是读取操作
* 3、规则
* List<Fruit> -->List<? extends Fruit>
* List<Apple> -->List<? extends Fruit>
* List<? extends Apple> -->List<? extends Fruit>
* 不能存放
* List<?>等同于下面这个↓
* List<? extends Object>
*/
public class Wildcard_Extends {
//泛型类
static class Test<T extends Fruit>{
}
//? extends Fruit
public static void test(List<? extends Fruit> list){
/*
*不能用于添加数据,
举个例子:如果这里把Apple添加进去了,看规则里面
List<FujiApple> app =new ArrayList<FujiApple>();
test(app);是编译可以通过的,然而这里的泛型定义的类型为FujiApple,
因为Apple、Fruit等都在FujiApple的父类或之上,所以会报错
list.add(new Apple());
list.add(new FujiApple());
list.add(new Pear());
list.add(new Fruit());
*/
list.add(null);
}
public static void main(String[] args) {
//extends 为上限,这里测试调用的为类
Test<Fruit> t1 =new Test<Fruit>();
Test<Apple> t2 =new Test<Apple>();
Test<Pear> t3 =new Test<Pear>();
//规则 ,这里测试调用的为方法
List<? extends Fruit> list1 =new ArrayList<Fruit>();
test(list1);
List<Fruit> list2 =new ArrayList<Fruit>();
test(list2);
List<Apple> list3 =new ArrayList<Apple>();
test(list3);
// ? extends Apple ,因为extends是<=,而Apple肯定<Fruit,所以肯定可以通过
List<? extends Apple> list4 =new ArrayList<FujiApple>();
test(list4);
//? -->为什么错误 ,因为 ? 等同于 ? extends Object
List<?> list5=new ArrayList();
//test(list5);
List<? extends Object> list6=new ArrayList<Object>();
//test(list6);
List<FujiApple> app =new ArrayList<FujiApple>();
test(app);
}
}
import java.util.ArrayList;
import java.util.List;
/**
* super : 泛型的下限 >= 即父类或自身
* 1、一般用于下限操作
* 2、能够添加数据上面,不能添加父对象
* 3、规则
* List<Fruit> -->List<? super Apple>
* List<Apple> -->List<? super Apple>
* List<? super Fruit> -->List<? super Apple>
* 不能存放
* List<? super FujiApple> -->List<?super Apple>
*/
public class Wildcard_Super {
public static void test(List<? super Apple> list){
list.add(new Apple());
list.add(new FujiApple());
/**list.add(new Fruit());
* 不能添加 父类对象*/
}
public static void main(String[] args) {
// >= 即父类或自身
List<Apple> list1 =new ArrayList<Apple>();
test(list1);
List<Fruit> list2 =new ArrayList<Fruit>();
test(list2);
List<Object> list3 =new ArrayList<Object>();
test(list3);
//规则
List<? super Apple> list4 =new ArrayList<Apple>();
test(list4);
List<? super Fruit> list5 =new ArrayList<Object>();
test(list5);
List<? super FujiApple> list6 =new ArrayList<Object>();
//test(list6);
List<?> list7 =new ArrayList<Object>();
//test(list7); 因为这里等同于List<? extends Object>
}
}
另外需要注意的一点是:泛型没有数组和多态,想实现多态的功能,可以使用通配符来替代
package genericity_supplement;
import java.util.ArrayList;
import java.util.List;
/**
* 1、泛型没有多态
* 2、泛型没有数组
*/
public class TestOthers {
public static void main(String[] args) {
//多态
@SuppressWarnings("unused")
Fruit f =new Apple();
/** List<Fruit> list =new ArrayList<Apple>();
* 泛型没有多态
*/
//使用通配符完成类似多态
List<? extends Fruit> list =new ArrayList<Apple>();
/**Fruit<String>[] arr =new Fruit<String>[10];
* 泛型没有数组
*/
//jdk1.7泛型简化
List<Fruit> list2 =new ArrayList<>();
}