java通配符

 Java泛型中的标记符含义: 

 E - Element (在集合中使用,因为集合中存放的是元素)

 - Type(Java 类)

 - Key(键)

 - Value(值)

 - Number(数值类型)

? -  表示不确定的java类型


关键字说明

●  ? 通配符类型

●  <? extends T> 表示类型的上界,表示参数化类型的可能是T 或是 T的子类

●  <? super T> 表示类型下界(Java Core中叫超类型限定),表示参数化类型是此类型的超类型(父类型),直至Object

? 通配符类型示例

类型通配符就是一个问号,将一个问号作为类型实参传给list集合,写作List<?>就可以。这种语法的意思是:List<?>是一个元素类型未知的list,然后list中add()的元素类型可以匹配任何类型。

<span style="font-size:14px;">public void test(List<?> list)  
    {  
        for (int i = 0; i < list.size(); i++)  
        {  
            System.out.println(list.get(i));  
        }  
    }  
      
    public static void main(String[] args)  
    {  
        Test test = new Test();  
        </span>List<String> list = new ArrayList<String>();  
<span style="font-size:14px;">       list.add("s");
        test.test(list);  
    }  </span>


在Java集合框架中,对于参数值是未知类型(即使用“?”通配符)的容器类,只能读取其中元素,不能向其中添加元素, 因为,其类型是未知,所以编译器无法识别添加元素的类型和容器的类型是否兼容,唯一的例外是NULL

示例:

  public static void main(String[] args) {
	    	
	    	
	    	List<? super test> fruits = null;
	    	test test = new test();  
		        List<?> list = new ArrayList();  
		        list.add("z");  //这里添加数据,无法添加成功
		        test.test(list);
	    }
	    
	    public void test(List<?> list)  
	    {  
	        for (int i = 0; i < list.size(); i++)  
	        {  
	            System.out.println(list.get(i));  
	        }  
	    }  
如上面的代码,添加数据是无法添加成功的。如果要添加数据,则必须这样写:

<span style="font-size:14px;"> </span>List<String> list = new ArrayList<String>();


extends 示例

在定义泛型类别时,预设可以使用任何的类型来实例化泛型类型中的类型。

    但是如果想限制使用泛型类别时,只能用某个特定类型或者是其子类型才能实例化该类型时,可以在定义类型时,使用extends关键字指定这个类型必须是继承某个类,或者实现某个接口,也可以是这个类或接口本身。


<span style="font-size:14px;">import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;

public class ListGenericFoo<T extends List>
{
    private T[] fooArray;

    public T[] getFooArray()
    {
        return fooArray;
    }

    public void setFooArray(T[] fooArray)
    {
        this.fooArray = fooArray;
    }
    
    public static void main(String[] args)
    {
        ListGenericFoo<LinkedList> foo1 = new ListGenericFoo<LinkedList>();
        ListGenericFoo<ArrayList> foo2 = new ListGenericFoo<ArrayList>();
        
        //Error: Bound mismatch
        //ListGenericFoo<HashMap> foo3 = new ListGenericFoo<HashMap>();
        
        LinkedList[] linkedLists = new LinkedList[10];
        foo1.setFooArray(linkedLists);
        
        ArrayList[] arrayLists = new ArrayList[10];
        foo2.setFooArray(arrayLists);
        
    }

}</span>

super 示例

通配符下限:<? super B>

  List<? super B> list = new ArrayList<A>();

  这样定义一个list的时候,允许向这个list添加对象。list可以接受其B类型和B的父类。像list中添加对象的时候编译器能确定确切类型。也可以这样理解:Fruit是Apple的父类,也是orange的父类。我们可以说Apple就是一个Fruit。

<span style="font-size:14px;">import java.util.ArrayList;
import java.util.List;
class A{}
class B extends A implements F{}
class C extends A{}
class D extends A{}
class E{}
interface F{}
public class Test{
    
    public void b(List<? super B> list){
        
        
        list.add(new B());     ////编译通过
        //list.add(new A());   //编译不能通过,要使用类型转换
        list.add((B) new A()); ////编译通过      
        
    }  
    public static void main(String[] args) {                
        List<? super B> listA = new ArrayList<A>();
        test.b(listA);
        
        
    
        
    }
}</span>

extends 可用于的返回类型限定,不能用于参数类型限定。

super 可用于参数类型限定,不能用于返回类型限定。

带有super超类型限定的通配符可以向泛型对易用写入,带有extends子类型限定的通配符可以向泛型对象读取。——《Core Java》



你可能感兴趣的:(泛型)