1.什么是泛型接口
泛型接口的定义: 在接口名后面加上泛型类型参数T,这样就定义了一个泛型接口。 例如:
public interface MyInterface<T>{
}
实例:
public interface IDao<T> {
void print(T obj);
}
public class IDaoImpl implements IDao<String> {
@Override
public void print(String obj) {
System.out.println("obj type is: " + obj.getClass().getName()+",value is:"+obj);
}
public static void main(String[] args) {
new IDaoImpl().print("hello,world!");
}
}
运行结果:
obj type is: java.lang.String,value is:hello,world!
2.泛型的上下界
上界用extends关键字声明,表示参数化的类型可能是所指定的类型,或者是此类型的子类。 下界用super进行声明,表示参数化的类型可能是所指定的类型,或者是此类型的父类型,直至Object。

形如 List<? extends B>,具体哪一种不能确定,既可以是 B,也可以是 C。在尝试执行 add() 方法时,List中的类型不能确定是具体哪一种,所以会编译报错。在执行 get() 方法时,不管是 B 还是 C,都可以以 A 类对象来接收。所以 List<? extends B> 不能添加元素,具有只读属性,只能获取。
形如 List<? super B>,具体哪一种不能确定,既可以是 B,也可以是 A,直至 Object类。在尝试执行 add() 方法时,虽然 List 的具体类型不能确定,但是根据多态, B 类及其子类的对象肯定都可以被赋值给 B 的对象,所以只能添加 B 类及其子类的对象。在尝试执行 get() 方法时,List 中的类型是 B 类或者其父类的具体一种,向上直至 Object 类,所以只能将获取的元素赋值给 Object 对象。
实例:
class Animal {
protected String alias;
public Animal(String alias) {
this.alias = alias;
}
}
class Cat extends Animal {
public Cat(String alias) {
super(alias);
}
@Override
public String toString() {
return "Cat{" +
"alias='" + alias + '\'' +
'}';
}
}
class Dog extends Animal {
public Dog(String alias) {
super(alias);
}
@Override
public String toString() {
return "Dog{" +
"alias='" + alias + '\'' +
'}';
}
}
public class GenerateDemo {
public static void main(String[] args) {
List<Animal> animalList = new ArrayList<Animal>();
List<Dog> dogs = new ArrayList<Dog>();
dogs.add(new Dog("旺财"));
List<Cat> cats = new ArrayList<Cat>();
cats.add(new Cat("Tom"));
//定义下界,只能接收Dog或者是Dog的父类的集合
List<? super Dog> list1 = dogs;
List<? super Dog> list2 = animalList;
list2.add(new Dog("黑贝")); //下界只能添加Dog或者Dog的子类对象。
//List<? super Dog> list3 = cats; //错误。
for(Object obj: list2){ //下界遍历只能使用Object.
System.out.println(obj);
}
//定义上界,只能接收Animal或者是Animal的子类
List<? extends Animal> animals1 = animalList;
List<? extends Animal> animals2 = dogs;
List<? extends Animal> animals3 = cats;
//注意:上界的集合是只读的,不能添加。
//animals2.add(new Dog("黑贝")); //注意上界集合不能添加
for (Animal a : animals2) {
System.out.println(a);
}
}
}
运行结果:
Dog{alias='黑贝'}
Dog{alias='旺财'}
小结:
1).? extends X 指明类型的上界限定为 X,表示传入方法的类型参数必须是其本身或子类。上界只能读取,不能添加。主要考虑到用于安全地访问数据,可以访问X及其子类型,并且不能写入非null的数据。
2).? super X ,指明类型的下界限定为 X,表示传入方法的类型参数必须是其本身或其父类。下界只能添加,不能读取。主要考虑用于安全地写入数据,可以写入X及其子类型。