黑马程序员技术交流社区

标题: 泛型中的?通配符 [打印本页]

作者: Sword    时间: 2013-4-30 01:56
标题: 泛型中的?通配符
本帖最后由 Sword 于 2013-5-3 23:53 编辑

问题一
定义一个方法,该方法用于打印出任意参数化类型的集合中的所有数据
错误方式:
public static void printCollection(Collection<Object> cols) {
                for(Object obj:cols) {
                        System.out.println(obj);
                }
                /* cols.add("string");//没错
                 cols = new HashSet<Date>();//会报告错误!*/
}
正确方式:
public static void printCollection(Collection<?> cols) {
                for(Object obj:cols) {
                        System.out.println(obj);
                }
                //cols.add("string");//错误,因为它不知自己未来匹配就一定是String
                cols.size();//没错,此方法与类型参数没有关系
                 cols = new HashSet<Date>();
        }
请帮忙具体解释一下两段代码出现错误和为什么正确的原因?

2.
Collection<?>  a可以与任意参数化的类型匹配,但到底匹配的是什么类型,只有以后才知道,所以,
a=new ArrayList<Integer>和a=new ArrayList<String>都可以, 但a.add(new Date())或a.add(“abc”)都不行,

想知道为什么不行?不行的原因具体是什么??





作者: 符立波    时间: 2013-4-30 09:59
null可以丢进去......
作者: 刘沛霞    时间: 2013-4-30 10:09

1.String 是Object的子类,HashSet也是Object的子类,但hashSet<Date>这个不是object的子类,如List<String>不是List<Object>的子类。所以才引入了通符符。

2.你出现Collection<?>  a可以与任意参数化的类型匹配,但到底匹配的是什么类型,只有以后才知道,所以,a=new ArrayList<Integer>和a=new ArrayList<String>都可以, 但a.add(new Date())或a.add(“abc”)都不行。  new Date 与 string 不是 collection的子类,是object的子类,只有继承自collection容器的子类才能使用。 希望能帮到你。
作者: 黄玉昆    时间: 2013-5-2 20:22
如果仍有问题,请继续追问,如果问题已解决,请将分类改为已解决,谢谢
作者: Sword    时间: 2013-5-3 00:17
黄玉昆 发表于 2013-5-2 20:22
如果仍有问题,请继续追问,如果问题已解决,请将分类改为已解决,谢谢

到现在就一个给回答的,在等等行吗?不介意的话,你帮忙回答一下吧?:)
作者: 黄玉昆    时间: 2013-5-3 08:16
问题一:
错误方式:
你首先要明白,Collection<Object> colse = new HashSet<Date>(),为什么不行。左右的限定类型必须一致,就像张老师说的一样,你不能把猪狗都放在圈里,不能把Date,String等都全放在Object的集合中;这个理解了,就好说了,cols.add("string"),只是将一个元素加入进去。而,你让cols = new HashSet<Date>()就是给cols限定为指定类型的集合了,你上面都指定只能放Object了,当然不能再放别的类型了。
正确方式:
Collection<?>代表的是你不知道别人传进来的是什么类型,所以用?表示,但是传进来的一定是唯一的类型,所以?是代表任意传入的唯一类型,打个比方说:比如造房子,工程人员不知道住户要安什么样的门,木门,铁门,玻璃门等,但是一定是一种类型的门,所以就接收任意类型的门,但是必须是唯一类型的。
所以,你不能具体操作集合中元素的类型,不能随意加入任意类型的元素(注意,是元素,不是限定类型)。能够cols = new HashSet<Date>()是因为先定义的Collection<?>,后指定的Date,就像是说你安了个玻璃门;但是一般来说,没有在方法内部这样赋值,都是提供给外界进行赋值。

第2个:
这里的?是代表的限定类型,在你没指定限定类型的时候,你把任意元素放进去,当然是不对的。你需要先指定你要存入的元素的类型才行。因为比如你加入的是“abc”,就相当于你这个问号就是String类型了,就相当于你造房子只能加玻璃门,这显然是不行的。

这种问题,其实很难解释清楚的,慢慢靠你自己的领会才能明白,如果不明白可以多联系生活,多思考就能知道其中的原因了。还有就是可以多看看API,找一下规律,你就能慢慢体会出来的。

个人说明一下:这几天确实比较忙,看到你的帖子是三天前的了,所以就提醒了一下。如果你的问题有人回答了,最好回复一下,这也是对你自己提问的负责,要不让我们会认为你没问题了,所以提醒了一下。并不是催你结帖,而是催你把自己的问题解决掉。
作者: Sword    时间: 2013-5-3 23:23
黄玉昆 发表于 2013-5-3 08:16
问题一:
错误方式:
你首先要明白,Collection colse = new HashSet(),为什么不行。左右的限定类型必须一 ...

回答的不错,谢谢了:)
作者: 黄玉昆    时间: 2013-5-3 23:30
Sword 发表于 2013-5-3 23:23
回答的不错,谢谢了

不知道我的回答,楼主可满意呢?如果还有什么不懂的,可以问哦,我知道的话会尽力解答的。如果楼主问题得到解决了,我很高兴帮你把问题回答清楚了。所以请楼主改一下帖子,因为每天审阅的帖子有点多,谢谢配合
作者: Sword    时间: 2013-5-3 23:40
黄玉昆 发表于 2013-5-3 23:30
不知道我的回答,楼主可满意呢?如果还有什么不懂的,可以问哦,我知道的话会尽力解答的。如果楼主问题得 ...

谢谢了,回答的很详细,很满意。不过我不知道怎么改成已解决,能帮忙回答一下吗?
作者: 黄玉昆    时间: 2013-5-4 07:49

在你的帖子下面有个编辑,点击这里就行了,然后选择分类





欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2