【泛型】_通配符笔记

时间:2021-12-09 19:25:51
 

【泛型】_通配符笔记

分类: Java
【泛型】_通配符笔记
本章目标:
掌握通配符“?”的使用
掌握受限泛型的设置
掌握泛型与子类继承的限制

3.1 匹配任意类型的通配符

匹配任意类型的通配符

在开发中对象的引用传递是最常见的,但是如果在泛型类的操作中,在进行引用传递的时候泛型类型必须匹配才可以传递,否则是无法传递的。

[java] view plaincopyprint?
  1. class Info<T>{  
  2.     private T var;    //定义泛型变量  
  3.     public void setVar(T var){  
  4.         this.var  = var;  
  5.     }  
  6.     public T getVar(){  
  7.         return this.var;  
  8.     }  
  9.     public String toString(){  
  10.         return this.var.toString();  
  11.     }  
  12. }  
  13. public class GenericsDemo12{  
  14.     public static void main(String[] args){  
  15.         Info<String> i = new Info<String>();  
  16.         i.setVar("MLDN");    //设置内容  
  17.         fun(i);  
  18.     }  
  19.     public static void fun(Info<Object> temp){  
  20.         System.out.println("内容:"+temp);  
  21.     }  
  22. }  



编译时错误:

泛型对象进行引用传递的时候,类型必须一致,如果现在非要传递,则可以将fun方法中Info参数的泛型取消掉。


[java] view plaincopyprint?
  1. class Info<T>{  
  2.     private T var;    //定义泛型变量  
  3.     public void setVar(T var){  
  4.         this.var  = var;  
  5.     }  
  6.     public T getVar(){  
  7.         return this.var;  
  8.     }  
  9.     public String toString(){  
  10.         return this.var.toString();  
  11.     }  
  12. }  
  13. public class GenericsDemo12{  
  14.     public static void main(String[] args){  
  15.         Info<String> i = new Info<String>();  
  16.         i.setVar("MLDN");    //设置内容  
  17.         fun(i);  
  18.     }  
  19.     public static void fun(Info temp){  
  20.         System.out.println("内容:"+temp);  
  21.     }  
  22. }  


以上确实完成了改进的功能,但是,代码似乎有些不是很妥当,毕竟之前已经指定过泛型了。


[java] view plaincopyprint?
  1. class Info<T>{  
  2.     private T var;    //定义泛型变量  
  3.     public void setVar(T var){  
  4.         this.var  = var;  
  5.     }  
  6.     public T getVar(){  
  7.         return this.var;  
  8.     }  
  9.     public String toString(){  
  10.         return this.var.toString();  
  11.     }  
  12. }  
  13. public class GenericsDemo12{  
  14.     public static void main(String[] args){  
  15.         Info<String> i = new Info<String>();  
  16.         i.setVar("MLDN");    //设置内容  
  17.         fun(i);  
  18.     }  
  19.     public static void fun(Info<?> temp){  
  20.         System.out.println("内容:"+temp);  
  21.     }  
  22. }  



如果使用?意味着可以接收任意的内容,但是此内容却无法直接使用<?>修饰的泛型对象时行修改。
[java] view plaincopyprint?
  1. class Info<T>{  
  2.     private T var;    //定义泛型变量  
  3.     public void setVar(T var){  
  4.         this.var  = var;  
  5.     }  
  6.     public T getVar(){  
  7.         return this.var;  
  8.     }  
  9.     public String toString(){  
  10.         return this.var.toString();  
  11.     }  
  12. }  
  13. public class GenericsDemo12{  
  14.     public static void main(String[] args){  
  15.         Info<?> i = new Info<String>();  
  16.         i.setVar("MLDN");    //设置内容  
  17.     }  
  18. }  



在使用<?>只能接收,但是不能修改。

3.2、受限泛型
之前设置泛型类型的时候,实际上都是可以任意设置的,只要是类就可以设置。但是在java的泛型中可以指定一个泛型的上限和下限。


设置上限:
声明对象:类名称<? extends 类> 对象名称
定义类:[访问权限] 类名称<泛型标识 extends 类>{}


设置下限:
声明对象:类名称<? super 类> 对象名称
定义类:[访问权限] 类名称<泛型标识 super 类>{}

3.2.1、设置上限

[java] view plaincopyprint?
  1. class Info<T>{  
  2.     private T var ;        // 定义泛型变量  
  3.     public void setVar(T var){  
  4.         this.var = var ;  
  5.     }  
  6.     public T getVar(){  
  7.         return this.var ;  
  8.     }  
  9.     public String toString(){    // 直接打印  
  10.         return this.var.toString() ;  
  11.     }  
  12. };  
  13. public class GenericsDemo18{  
  14.     public static void main(String args[]){  
  15.         Info<String> i1 = new Info<String>() ;        // 声明String的泛型对象  
  16.         i1.setVar("hello") ;  
  17.         fun(i1) ;  
  18.     }  
  19.     public static void fun(Info<? extends Number> temp){    // 只能接收Number及其Number的子类  
  20.         System.out.print(temp + "、") ;  
  21.     }  
  22. };  



[java] view plaincopyprint?
  1. class Info<T extends Number>{    // 此处泛型只能是数字类型  
  2.     private T var ;        // 定义泛型变量  
  3.     public void setVar(T var){  
  4.         this.var = var ;  
  5.     }  
  6.     public T getVar(){  
  7.         return this.var ;  
  8.     }  
  9.     public String toString(){    // 直接打印  
  10.         return this.var.toString() ;  
  11.     }  
  12. };  
  13. public class GenericsDemo19{  
  14.     public static void main(String args[]){  
  15.         Info<Integer> i1 = new Info<Integer>() ;        // 声明Integer的泛型对象  
  16.     }  
  17. };  



[java] view plaincopyprint?
  1. class Info<T extends Number>{    // 此处泛型只能是数字类型  
  2.     private T var ;        // 定义泛型变量  
  3.     public void setVar(T var){  
  4.         this.var = var ;  
  5.     }  
  6.     public T getVar(){  
  7.         return this.var ;  
  8.     }  
  9.     public String toString(){    // 直接打印  
  10.         return this.var.toString() ;  
  11.     }  
  12. };  
  13. public class GenericsDemo20{  
  14.     public static void main(String args[]){  
  15.         Info<String> i1 = new Info<String>() ;        // 声明Integer的泛型对象  
  16.     }  
  17. };  


3.2.2、设置下限

[java] view plaincopyprint?
  1. class Info<T>{  
  2.     private T var ;        // 定义泛型变量  
  3.     public void setVar(T var){  
  4.         this.var = var ;  
  5.     }  
  6.     public T getVar(){  
  7.         return this.var ;  
  8.     }  
  9.     public String toString(){    // 直接打印  
  10.         return this.var.toString() ;  
  11.     }  
  12. };  
  13. public class GenericsDemo21{  
  14.     public static void main(String args[]){  
  15.         Info<String> i1 = new Info<String>() ;        // 声明String的泛型对象  
  16.         Info<Object> i2 = new Info<Object>() ;        // 声明Object的泛型对象  
  17.         i1.setVar("hello") ;  
  18.         i2.setVar(new Object()) ;  
  19.         fun(i1) ;  
  20.         fun(i2) ;  
  21.     }  
  22.     public static void fun(Info<? super String> temp){    // 只能接收String或Object类型的泛型  
  23.         System.out.print(temp + "、") ;  
  24.     }  
  25. };  


[java] view plaincopyprint?
  1. class Info<T>{  
  2.     private T var ;        // 定义泛型变量  
  3.     public void setVar(T var){  
  4.         this.var = var ;  
  5.     }  
  6.     public T getVar(){  
  7.         return this.var ;  
  8.     }  
  9.     public String toString(){    // 直接打印  
  10.         return this.var.toString() ;  
  11.     }  
  12. };  
  13. public class GenericsDemo22{  
  14.     public static void main(String args[]){  
  15.         Info<Integer> i1 = new Info<Integer>() ;        // 声明Integer的泛型对象  
  16.         i1.setVar(30) ;  
  17.         fun(i1) ;  
  18.     }  
  19.     public static void fun(Info<? super String> temp){    // 只能接收String或Object类型的泛型  
  20.         System.out.print(temp + "、") ;  
  21.     }  
  22. };  




3.3、解释:泛型与子类继承的限制

一个类的子类可以通过对象多态性,为其父类实例化,但是在泛型操作中,子类的泛型类型是无法使用父类的泛型类型接收的,例如:Info<String>不能使用Info<Object>接收
[java] view plaincopyprint?
  1. class Info<T>{  
  2.     private T var ;        // 定义泛型变量  
  3.     public void setVar(T var){  
  4.         this.var = var ;  
  5.     }  
  6.     public T getVar(){  
  7.         return this.var ;  
  8.     }  
  9.     public String toString(){    // 直接打印  
  10.         return this.var.toString() ;  
  11.     }  
  12. };  
  13. public class GenericsDemo23{  
  14.     public static void main(String args[]){  
  15.         Info<String> i1 = new Info<String>() ;        // 泛型类型为String  
  16.         Info<Object> i2 = null ;  
  17.         i2 = i1 ;  
  18.     }  
  19. };  



GenericsDemo23.java:17: 不兼容的类型
找到: Info<java.lang.String>
需要: Info<java.lang.Object>
                i2 = i1 ;
                     ^
1 错误