当前位置: 代码迷 >> Java相关 >> 限制泛型可用部类,类型通配符声明,泛型方法
  详细解决方案

限制泛型可用部类,类型通配符声明,泛型方法

热度:39   发布时间:2016-04-22 19:09:03.0
限制泛型可用类型,类型通配符声明,泛型方法

一、限制泛型可用类型

①   在定义泛型类型时,默认在实例化泛型类的时候可以使用任何类型,但是如果想要限制使用泛型类型时,只能用某个特定类型或者是其子类型才能实例化该类型时,可以在定义类型时,使用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 }

 

  相关解决方案