9.3.1 使用类型通配符
9.3.1 使用类型通配符
为了表示各种泛型List
的父类,可以使用类型通配符,类型通配符是一个问号(?
),将一个问号作为类型实参传给List
集合,写作:List<?>
(意思是元素类型未知的List
)。这个问号(?
)被称为通配符,它的元素类型可以匹配任何类型。可以将上面方法改写为如下形式:
1 | public void test(List<?> c){ |
现在使用任何类型的List
来调用它,程序依然可以访问集合c中的元素,其类型是Object
,这永远是安全的,因为不管List
的真实类型是什么,它包含的都是Object
。
通配符?可以作为任意泛型形参的实参
上面程序中使用的List<?>
,其实这种写法可以适应于任何支持泛型声明的接口和类,比如写成Set<?>
、 Collection<?>
、Map<?,?>
。
但这种带通配符的List<?>
仅表示它是各种泛型List
的父类,并不能把元素加入到其中。例如,如下代码将会引起编译错误:
1 | List<?> list= new ArrayList<String>(); |
因为程序无法确定c集合中元素的类型,所以不能向其中添加对象。根据前面的List<E>
接口定义的代码可以发现:add()
方法有类型参数E作为集合的元素类型,所以传给add
的参数必须是E类的对象或者其子类的对象。但因为在该例中不知道E是什么类型,所以程序无法将任何对象“丢进”该集合。唯一的例外是null
,因为null
是所有引用类型的实例。
另一方面,程序可以调用get()
方法来返回List<?>
集合指定索引处的元素,其返回值是一个未知类型,但可以肯定的是,它总是一个Object
。因此,把get()
的返回值赋值给一个Object
类型的变量,或者放在任何希望是Object
类型的地方都可以。