泛型(3)-类型通配符

    正如前面讲的,当使用一个泛型类时(包括声明变量和创建对象两种情况),都应该为这个泛型类传入一个类型实参,如果没有传入类型实际参数,编译器就会提出泛型警告,结社现在需要定义一个方法,该方法里有一个集合形参,集合形参的元素类型时不确定的,那么该怎么定义呢?

import java.util.ArrayList;
import java.util.List;
public class Demo1 {
public void test(List<Object> list){
for (int i=0;i<list.size();i++){
System.out.println(list.get(i));
}
}
public static void main(String[] args) {
//创建一个Demo1对象
Demo1 demo1=new Demo1();
//创建一个list集合
List<String>list=new ArrayList<>();
demo1.test(list);//编译错误
}
}

上面程序编译错误,表明List<String>并不能被当成List<Object>对象使用,也就是说List<String>并不是List<Object>的子类
String是Object的一个子类型(子类或者子接口),List是具有泛型声明的类或者接口,然而List<String>却并不是List<Object>的子类型!这一点非常值得注意,与大部分人的习惯认知不同
Java泛型的设计原则是,只要代码在编译时没有出现警告,就不会遇到运行时ClassCastException异常.
数组和泛型的不同之处:
假设Foo是Bar的一个子类型(子类或者子接口),那么Foo[]也是Bar[]的子类型,但G<Foo>并不是G<Bar>的子类型(子类或者接口).Foo[]自动向上转型为Bar[],方式称之为型变.
代码如下:
Integer [] ia=new Integer[5];bei
Number [] na=ia;
na[0]=0.5;//编译不报错,运行时引发ArrayStoreException异常.


=============================================================================================================================================
使用类型通配符
  为了表示各种泛型List的父类,可以使用类型通配符,类型通配符是一个'?',将一个问号作为类型实参传给List集合,写作:List<?>(意思是元素类型未知的List).这个问号(?)被称为通配符,它的元素类型可以匹配任何类型,
可以将上面的代码修改如下
public void test(List<?> list){
for(int i=0;i<list.size();i++){
system.out.print(list.get(i))
}}
现在使用任何类型的List来调用它,程序依然可以访问集合list中的元素,其类型是Object,永远是安全的,因为不管List的真实类型是什么,它包含的都是Object,除了List<?>,这种写法还适用于任何支持泛型声明的接口和类.
如Set<?>,Collection<?>,Map<?,?>等.
package com.j1803.Type_wildcards;

import java.util.ArrayList;
import java.util.List;

public class Demo1 {

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) {
//创建一个Demo1对象
Demo1 demo1=new Demo1();
//创建一个list集合
List<String>list=new ArrayList<>();
demo1.test(list);//编译错误

List<Integer>list1=new ArrayList<>();
list1.add(1);
list1.add(2);
list1.add(3);
demo1.test(list1);
}
}
answer:
1
2
3

但这种带有通配符的List仅表示它是各种泛型List的父类,并不能把元素放入其中.例如,下面代码进会引起编译错误.
List<?> c=new ArrayList<>();
c.add(new Object());//出现编译错误
原因是程序无法确定c集合中元素的类型,所以不能向其中添加对象.




 
posted @ 2018-09-16 13:46  zhou_shadow  阅读(585)  评论(0编辑  收藏  举报