編程小知識【java-0006】java泛型機(jī)制-泛型的上下限
<? extends A>
表示該類型參數(shù)可以是A(上邊界)或者A的子類類型。編譯時擦除到類型A,即用A類型代替類型參數(shù)。
在使用泛型的時候,我們可以為傳入的泛型類型實參進(jìn)行上下邊界的限制,如:類型實參只準(zhǔn)傳入某種類型的父類或某種類型的子類。
上限
class Demo01<T extends Number>{ ? ?// 此處泛型只能是數(shù)字類型
? ?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);
? ?}
}
使用原則
為了獲得最大限度的靈活性,要在表示 生產(chǎn)者或者消費者 的輸入?yún)?shù)上使用通配符,使用的規(guī)則就是:生產(chǎn)者有上限、消費者有下限
如果參數(shù)化類型表示一個 T 的生產(chǎn)者,使用 < ? extends T>;
如果它表示一個 T 的消費者,就使用 < ? super T>;
如果既是生產(chǎn)又是消費,那使用通配符就沒什么意義了,因為你需要的是精確的參數(shù)類型。
總結(jié)
<?> 無限制通配符
<? extends E> extends 關(guān)鍵字聲明了類型的上界,表示參數(shù)化的類型可能是所指定的類型,或者是此類型的子類
<? super E> super 關(guān)鍵字聲明了類型的下界,表示參數(shù)化的類型可能是指定的類型,或者是此類型的父類