程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> JAVA編程 >> JAVA綜合教程 >> 限制泛型可用類型,類型通配符聲明,泛型方法,通配符聲明

限制泛型可用類型,類型通配符聲明,泛型方法,通配符聲明

編輯:JAVA綜合教程

限制泛型可用類型,類型通配符聲明,泛型方法,通配符聲明


一、限制泛型可用類型

①   在定義泛型類型時,默認在實例化泛型類的時候可以使用任何類型,但是如果想要限制使用泛型類型時,只能用某個特定類型或者是其子類型才能實例化該類型時,可以在定義類型時,使用extends關鍵字指定這個類型必須是繼承某個類,或者實現某個類;

②   當沒有指定泛型繼承的類型或接口時,默認使用extends Object,所以默認情況下任何類型都可以作為參數傳入;

繼承抽象類

1 public class GenericDemo3{ 2 public static void main(String []args){ 3 GenericClass<Dog> dogClass=new GenericClass<Dog>(); 4 dogClass.setObj(new Dog()); 5 dogClass.getObj().eat(); 6 7 8 GenericClass<Cat> catClass=new GenericClass<Cat>(); 9 catClass.setObj(new Cat()); 10 catClass.getObj().eat(); 11 } 12 } 13 14 //泛型類所接受的參數做了限制,只能接收Animal類型或者Animal類的子類 15 class GenericClass<T extends Animal>{ 16 private T obj; 17 public void setObj(T obj){ 18 this.obj=obj; 19 } 20 public T getObj(){ 21 return obj; 22 } 23 } 24 25 abstract class Animal{ 26 public abstract void eat(); 27 } 28 29 class Dog extends Animal{ 30 public void eat(){ 31 System.out.println("啃骨頭"); 32 } 33 } 34 class Cat extends Animal{ 35 public void eat(){ 36 System.out.println("吃魚肉"); 37 } 38 } View Code

繼承接口

1 public class GenericDemo3{ 2 public static void main(String []args){ 3 GenericClass<Dog> dogClass=new GenericClass<Dog>(); 4 dogClass.setObj(new Dog()); 5 dogClass.getObj().eat2(); 6 7 8 GenericClass<Cat> catClass=new GenericClass<Cat>(); 9 catClass.setObj(new Cat()); 10 catClass.getObj().eat2(); 11 } 12 } 13 14 //泛型類所接受的參數做了限制,只能接收Animal類型或者Animal類的子類 15 class GenericClass<T extends Animal2>{ 16 private T obj; 17 public void setObj(T obj){ 18 this.obj=obj; 19 } 20 public T getObj(){ 21 return obj; 22 } 23 } 24 25 interface Animal2{ 26 public abstract void eat2(); 27 } 28 29 class Dog implements Animal2{ 30 public void eat2(){ 31 System.out.println("啃骨頭2"); 32 } 33 } 34 class Cat implements Animal2{ 35 public void eat2(){ 36 System.out.println("吃魚肉2"); 37 } 38 } View Code

 

二、類型通配符聲明

①   同一泛型類,如果實例化時給定的實際類型不同,則這些實例的類型是不兼容的,不能相互賦值;

Generic<Boolean> f1=new Generic<Boolean>();

Generic<Integer> f2=new Generic<Integer>();

f1=f2;//發生編譯錯誤

Generic<Object> f=f1;//f1和f類型並不兼容,發生編譯錯誤

f=f2;//f2和f類型同樣不兼容,也會發生編譯錯誤

②   泛型類實例之間的不兼容性會帶來使用的不便。我們可以使用泛型通配符(?)聲明泛型類的變量就可以解決這個問題;

③   泛型通配符的方式

“?”代表任意一個類型;

Generic<Boolean> f1=new Generic<Boolean>();

Generic<?> f=f1;

和限制泛型的上限相似,同樣可以使用extends關鍵字限定通配符匹配類型的上限;

Generic<Dog> f1=new Generic<Dog>();

Generic<? extends Animal> f=f1;

還可以使用super關鍵字將通配符類型限定為某個類型及其父類型;

Generic<Animal> f1=new Generic<Animal>();

Generic<? super Dog> f=f1;

1 public class GenericDemo4{ 2 public static void main(String []args){ 3 GenericClass<Dog> dogClass=new GenericClass<Dog>(); 4 dogClass.setObj(new Dog()); 5 dogClass.getObj().eat(); 6 7 GenericClass<Cat> catClass=new GenericClass<Cat>(); 8 catClass.setObj(new Cat()); 9 catClass.getObj().eat(); 10 11 GenericClass<String> StringClass=new GenericClass<String>(); 12 13 //dogClass=catClass;//編譯出錯 14 15 //無限定通配符的使用 16 GenericClass<?> gClass=null; 17 gClass=dogClass; 18 ((Dog)gClass.getObj()).eat();//因父類為object類型,所以要強制轉換 19 20 gClass=StringClass; 21 22 //上邊界限定通配符 23 GenericClass<? extends Animal> subclass=null; 24 subclass=dogClass; //Animal a=dog; 25 subclass.getObj().eat(); 26 27 //下邊界限定通配符 28 GenericClass<? super Dog> sclass=null; 29 GenericClass<Animal> cClass=new GenericClass<Animal>(); 30 //sclass=catClass; //編譯錯誤,類型不兼容 31 sclass=cClass;//可以通過編譯 32 } 33 } 34 35 36 class GenericClass<T>{ 37 private T obj; 38 public void setObj(T obj){ 39 this.obj=obj; 40 } 41 public T getObj(){ 42 return obj; 43 } 44 } 45 46 interface Animal{ 47 public abstract void eat(); 48 } 49 50 class Dog implements Animal{ 51 public void eat(){ 52 System.out.println("啃骨頭"); 53 } 54 } 55 class Cat implements Animal{ 56 public void eat(){ 57 System.out.println("吃魚肉"); 58 } 59 } View Code

 

三、泛型方法

①   不僅類可以聲明泛型,類中的方法也可以聲明僅用於自身的泛型,這種方法叫做泛型方法。其定義格式為:

 

訪問修飾符<泛型列表> 返回類型 方法名(參數列表){

           實現代碼

}

②   在泛型列表中聲明的泛型,可用於該方法的返回類型聲明、參數類型聲明和方法代碼中的局部變量的類型聲明;

③   類中其它方法不能使用當前方法聲明的泛型;

注:是否擁有泛型方法,與其所在的類是否泛型沒有關系。要定義泛型方法,只需將泛型參數列表置於返回值前;

④   什麼時候使用 泛型方法,而不是泛型類?

添加類型約束只作用於一個方法的多個參數之間,而不涉及到類中的其它方法;

施加類型約束的方法為靜態方法,只能將其定義為泛型方法,因為靜態方法不能使用其所在類的類型參數;

 1 public class GenericDemo5{
 2     public static void main(String []args){
 3         GenericClass2 gen=new GenericClass2();
 4         gen.println("abc");
 5         gen.println(true);
 6         gen.println(10);
 7         gen.println(10.5);
 8         gen.println(new Dog());
 9         gen.println(new Cat());
10         GenericClass2.print("哈哈");
11     }
12 }
13 
14 class GenericClass2{
15     //泛型方法
16     public <T> void println(T content){
17         System.out.println(content);
18     }
19     //泛型方法的重載
20     public <T extends Animal> void println(T animal){
21         animal.eat();
22     }
23     
24     public static <T> void print(T content){
25         System.out.println(content);
26     }
27 }
28 
29 interface Animal{
30     public abstract void eat();
31 }
32 
33 class Dog implements Animal{
34     public void eat(){
35         System.out.println("啃骨頭");
36     }
37 }
38 class Cat implements Animal{
39     public void eat(){
40         System.out.println("吃魚肉");
41     }
42 }

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved