编程小知识【java-0006】java泛型机制-泛型的上下限
<? extends A>
表示该类型参数可以是A(上边界)或者A的子类类型。编译时擦除到类型A,即用A类型代替类型参数。
在使用泛型的时候,我们可以为传入的泛型类型实参进行上下边界的限制,如:类型实参只准传入某种类型的父类或某种类型的子类。
上限
class Demo01<T extends Number>{ // 此处泛型只能是数字类型
private T var ; // 定义泛型变量
public void setVar(T var){
this.var = var;
}
public T getVar(){
return this.var;
}
public String toString(){ // 直接打印
return this.var.toString();
}
}
public class TestDemo01{
public static void main(String args[]){
// 声明Integer的泛型对象
Demo01<Integer> d = new Demo01<Integer>();
}
}
class Demo02<T>{
private T var ; // 定义泛型变量
public void setVar(T var){
this.var = var;
}
public T getVar(){
return this.var;
}
public String toString(){ // 直接打印
return this.var.toString();
}
}
public class TestDemo02{
public static void main(String args[]){
Demo02<String> d1 = new Demo02<String>(); // 声明String的泛型对象
Demo02<Object> d2 = new Demo02<Object>(); // 声明Object的泛型对象
d1.setVar("hello");
d2.setVar(new Object());
fun(d1);
fun(d2);
}
public static void fun(Demo02<? super String> temp){ // 只能接收String或Object类型的泛型,String类的父类只有Object类
System.out.println(temp);
}
}
使用原则
为了获得最大限度的灵活性,要在表示 生产者或者消费者 的输入参数上使用通配符,使用的规则就是:生产者有上限、消费者有下限
如果参数化类型表示一个 T 的生产者,使用 < ? extends T>;
如果它表示一个 T 的消费者,就使用 < ? super T>;
如果既是生产又是消费,那使用通配符就没什么意义了,因为你需要的是精确的参数类型。
总结
<?> 无限制通配符
<? extends E> extends 关键字声明了类型的上界,表示参数化的类型可能是所指定的类型,或者是此类型的子类
<? super E> super 关键字声明了类型的下界,表示参数化的类型可能是指定的类型,或者是此类型的父类