• Java 泛型学习三 通配符


    Java 泛型学习一 泛型概念
    Java 泛型学习二 泛型的限制
    Java 泛型学习三 通配符
    Java 泛型学习四 自动擦除
    Java 泛型学习五 泛型擦除带来的不自然
    Java 泛型学习六 泛型类型系统

    什么是泛型通配符

    我们来看看泛型的类型变量的继承吧,按照常规的继承理解,下面代码应该是没问题的:

    package net.oseye;
    
    import java.util.ArrayList;
    public class FanXing {
    	public static void main(String[] args) {
    		ArrayList<String> as=new ArrayList<String>();
    		ArrayList<Object> ao=null;
    		ao=as;
    	}
    }

    因为任何类都继承自Object类,但却不能通过编译:

    net\oseye\FanXing.java:9: 错误: 不兼容的类型
                    ao=as;
                       ^
      需要: ArrayList<Object>
      找到:    ArrayList<String>
    1 个错误
    

    可以总结出若A是B的子类,则G<A>可以当做G<B>使用并不成立。

    如果想要达到目的就要使用通配符“?”,通配符“?”代表任意具体类型,如上述代码改成:

    package net.oseye;
    
    import java.util.ArrayList;
    public class FanXing {
    	public static void main(String[] args) {
    		ArrayList<String> as=new ArrayList<String>();
    		ArrayList<?> ao=null;
    		ao=as;
    	}
    }

    就可以编译通过。


    使用泛型通配符注意事项:


    1. 泛型通配符只能用于引用的声明中,不可以在创建对象时使用;
      package net.oseye;
      
      public class FanXing {
      	public static void main(String[] args) {
      		Fruit<?> fruit=new Fruit<?>();
      	}
      }
      
      class Fruit<T>{
      	private T color;
      	public void setColor(T color){
      		this.color=color;		
      	}
      	public String getColor(){
      		return this.color.toString();		
      	}
      }
      上述代码是编译不通过的,异常:
      net\oseye\FanXing.java:5: 错误: 意外的类型
                      Fruit<?> fruit=new Fruit<?>();
                                              ^
        需要: 不带限制范围的类或接口
        找到:    ?
      1 个错误
      
    2. 不可以使用采用了泛型通配符的引用调用使用了泛型参数的方法;
      package net.oseye;
      
      public class FanXing {
      	public static void main(String[] args) {
      		Fruit<?> fruit=new Fruit<String>();
      		fruit.setColor("red");
      	}
      }
      
      class Fruit<T>{
      	private T color;
      	public void setColor(T color){
      		this.color=color;		
      	}
      	public String getColor(){
      		return this.color.toString();		
      	}
      }
      上述代码也不能通过编译,异常:
      net\oseye\FanXing.java:6: 错误: 无法将类 Fruit<T>中的方法 setColor应用到给定类型
      ;
                      fruit.setColor("red");
                           ^
        需要: CAP#1
        找到: String
        原因: 无法通过方法调用转换将实际参数String转换为CAP#1
        其中, T是类型变量:
          T扩展已在类 Fruit中声明的Object
        其中, CAP#1是新类型变量:
          CAP#1从?的捕获扩展Object
      1 个错误
      
    3. 通配符也可以限制的,语法:? extends 类名或接口名
      package net.oseye;
      
      public class FanXing {
      	public static void main(String[] args) {
      		Apple<String> appleStr=new Apple<String>();
      		appleStr.setColor("红色");
      		
      		Apple<Integer> appleNum=new Apple<Integer>();
      		appleNum.setColor(1);
      		
      		SayColor(appleStr);
      		SayColor(appleNum);
      	}
      	
      	static void SayColor(Apple<? extends String> apple){
      				System.out.println(apple.getColor());
      	}
      }
      
      class Apple<T>{
      	private T color;
      	public void setColor(T color){
      		this.color=color;		
      	}
      	public T getColor(){
      		return this.color;		
      	}
      }
      异常信息可以看得出限制起到了作用:
      net\oseye\FanXing.java:12: 错误: 无法将类 FanXing中的方法 SayColor应用到给定类型
      ;
                      SayColor(appleNum);
                      ^
        需要: Apple<? extends String>
        找到: Apple<Integer>
        原因: 无法通过方法调用转换将实际参数Apple<Integer>转换为Apple<? extends String
      >
      1 个错误
  • 相关阅读:
    mongodb python image 图像存储读取
    python 编码 UnicodeDecodeError
    UnicodeDecodeError: 'gbk' codec can't decode byte 0xff in position 0: illegal multibyte sequence
    eclipse emacs
    mongodb windows install &python
    虚度的日子们
    C# list与数组互相转换
    C# 一个多层循环中,break一次能跳出几个循环?
    C# Byte[]、Image、Bitmap 之间的相互转换
    C# 写入和读出文本文件
  • 原文地址:https://www.cnblogs.com/zhaiqianfeng/p/4618362.html
Copyright © 2020-2023  润新知