Java泛型中通配符的使用
來源:程序員人生 發(fā)布時間:2016-07-13 10:09:14 閱讀次數(shù):2486次
學(xué)習(xí)目標(biāo)
掌握通配符“?” 的使用
掌握受限泛型的設(shè)置
掌握泛型與子類繼承的限制
匹配任意類型的通配符
在開發(fā)中對象的援用傳遞是最多見的,但是如果在泛型類的操作中,在進行傳遞的時候泛型類型必須匹配才可以傳遞。否則是沒法傳遞的。
class Info<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 GenericsDemo12{
public static void main(String args[]){
Info<String> i = new Info<String>() ; // 使用String為泛型類型
i.setVar("lx") ; // 設(shè)置內(nèi)容
fun(i) ;
}
public static void fun(Info<Object> temp){ // 接收Object泛型類型的Info對象
System.out.println("內(nèi)容:" + temp) ;
}
};
編譯時就出現(xiàn)毛病:
泛型對象進行援用傳遞的時候,類型必須1致。如果現(xiàn)在非要傳遞,則可以將fun方法中的泛型取消掉。以下所示:
class Info<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 GenericsDemo13{
public static void main(String args[]){
Info<String> i = new Info<String>() ; // 使用String為泛型類型
i.setVar("WWWW") ; // 設(shè)置內(nèi)容
fun(i) ;
}
public static void fun(Info temp){ // 接收Object泛型類型的Info對象
System.out.println("內(nèi)容:" + temp) ;
}
};
發(fā)現(xiàn)有正告提示:

但不會影響程序的運行:
以上確切完成了改進的功能,但是,代碼似乎有些不是很妥當(dāng),畢竟之前已指定過泛型了。
如果使用?呢?以下所示:
class Info<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 GenericsDemo14{
public static void main(String args[]){
Info<String> i = new Info<String>() ; // 使用String為泛型類型
i.setVar("MLDN") ; // 設(shè)置內(nèi)容
fun(i) ;
}
public static void fun(Info<?> temp){ // 可以接收任意的泛型對象
System.out.println("內(nèi)容:" + temp) ;
}
};
能照舊運行,而且不會有正告。
注意:如果使用?意味著可以接收任意的內(nèi)容,但是此內(nèi)容卻沒法直接使用<?> 修飾的泛型對象進行修改。以下所示:
class Info<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 GenericsDemo15{
public static void main(String args[]){
Info<?> i = new Info<String>() ; // 使用String為泛型類型
i.setVar("MLDN") ; // 設(shè)置內(nèi)容
}
};
發(fā)現(xiàn)有毛病,正告和運行結(jié)果分別以下所示:
也就是說,在使用戶<?> 只能接收。但是不能修改。
受限泛型
之前設(shè)置泛型類型的時候,實際上都是可以任意設(shè)置的,只要是類就能夠設(shè)置。但是在Java的泛型中可以指定1個泛型的上限和下限。范圍的上限使用extends關(guān)鍵字聲明,表示參數(shù)化的類型多是所指定的類型,或是此類型的子類。而范圍下限使用super進行聲明,表示參數(shù)化的類型多是所指定的類型,或是此類型的父類型,直至Object類。
設(shè)置上限:
聲明對象:類名稱<? extends 類> 對象名稱
定義類: [訪問權(quán)限] 類名稱<泛型標(biāo)示 extends 類>{}
設(shè)置下限:
聲明對象:類名稱<? super 類> 對象名稱
定義類:[訪問權(quán)限] 類名稱<泛型標(biāo)示 super 類>{}
設(shè)置上限
class Info<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 GenericsDemo17{
public static void main(String args[]){
Info<Integer> i1 = new Info<Integer>() ; // 聲明Integer的泛型對象
Info<Float> i2 = new Info<Float>() ; // 聲明Float的泛型對象
i1.setVar(30) ; // 設(shè)置整數(shù),自動裝箱
i2.setVar(30.1f) ; // 設(shè)置小數(shù),自動裝箱
fun(i1) ;
fun(i2) ;
}
public static void fun(Info<? extends Number> temp){ // 只能接收Number及其Number的子類
System.out.print(temp + "、") ;
}
};
如果在方法中傳遞的不是泛型標(biāo)示不是Number及其子類,則會報錯,以下所示:
class Info<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 GenericsDemo18{
public static void main(String args[]){
Info<String> i1 = new Info<String>() ; // 聲明String的泛型對象
i1.setVar("hello") ;
fun(i1) ;
}
public static void fun(Info<? extends Number> temp){ // 只能接收Number及其Number的子類
System.out.print(temp + "、") ;
}
};
在類中也能夠使用泛型,以下所示:
class Info<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 GenericsDemo19{
public static void main(String args[]){
Info<Integer> i1 = new Info<Integer>() ; // 聲明Integer的泛型對象
}
};
如果現(xiàn)在在使用Info的時候設(shè)置成了String類型,則在編譯的時候就會出現(xiàn)毛病。
class Info<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 GenericsDemo20{
public static void main(String args[]){
Info<String> i1 = new Info<String>() ; // 聲明Integer的泛型對象
}
};
設(shè)置下限
當(dāng)使用的泛型只能在本類和父類類型利用的時候,就必須使用泛型的范圍下限配置
class Info<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 GenericsDemo21{
public static void main(String args[]){
Info<String> i1 = new Info<String>() ; // 聲明String的泛型對象
Info<Object> i2 = new Info<Object>() ; // 聲明Object的泛型對象
i1.setVar("hello") ;
i2.setVar(new Object()) ;
fun(i1) ;
fun(i2) ;
}
public static void fun(Info<? super String> temp){ // 只能接收String或Object類型的泛型
System.out.print(temp + "、") ;
}
};
如果現(xiàn)在使用了Integer作為泛型的類型,則不滿足泛型的下限。以下所示:
class Info<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 GenericsDemo22{
public static void main(String args[]){
Info<Integer> i1 = new Info<Integer>() ; // 聲明Integer的泛型對象
i1.setVar(30) ;
fun(i1) ;
}
public static void fun(Info<? super String> temp){ // 只能接收String或Object類型的泛型
System.out.print(temp + "、") ;
}
};
解釋:泛型與子類繼承的限制
1個類的子類可以通過對象多態(tài)性,為其父類實例化,但是在泛型操作中,子類的泛型類型是沒法使用父類的泛型類型接收的,例如:Info<String> 不能使用Info<Object>接收。
實例以下:
class Info<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 GenericsDemo23{
public static void main(String args[]){
Info<String> i1 = new Info<String>() ; // 泛型類型為String
Info<Object> i2 = null ;
i2 = i1 ;
}
};

發(fā)現(xiàn)有毛病提示。
總結(jié):
1、使用?可以接收任意的泛型類型。
2、泛型的上限:? extends 類型。
3、泛型的下限用的不是太多。
4、了解為何泛型子類之間的繼承沒法直接轉(zhuǎn)換的緣由。
生活不易,碼農(nóng)辛苦
如果您覺得本網(wǎng)站對您的學(xué)習(xí)有所幫助,可以手機掃描二維碼進行捐贈