A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 李敬卫 中级黑马   /  2013-1-23 20:09  /  1663 人查看  /  6 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

public class ZiDingFanXing2 {

public static <T> void  copy1(Collection<T> des,T[] src){

}
public static <T> void  copy2(T[] des,T[] src){

}
public static void main(String[] args) {
copy2(new Date[2],new String[3]);
copy1(new ArrayList<Date>(),new String[3]);//编译报错
}
}
对于这道题:我有两个疑问。
1.copy2方法中为什么可以传入不同类型的数组?
2.copy1方法中为什么就不可以传入不同的类型呢?

评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

6 个回复

倒序浏览
本帖最后由 黑马张英涛 于 2013-1-23 21:39 编辑

这个问题应该是泛型的类型推断机制造成的,对于copy2方法,虽然你传入的两个参数类型不一致,
但是泛型的这种机制会找出它们共同的类型来,即本身不一致就找父类型,一直找出一致的类型来,
所以在你给copy2传递了这两个参数以后T的类型就被确定为Object了;
对于copy1方法,同样可以确定T的类型为Object,但是由于存在集合类,编译器会检查类型是否匹配,
由于前面已经确定了T的类型为Object,即ArrayList应该接受Object类型的数据,
但是你却让他接受Date类型的数据,这就造成了类型不匹配,所以编译报错。
你可以将Date改为Object验证一下就明白了。

评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

回复 使用道具 举报
黑马张英涛 发表于 2013-1-23 21:38
这个问题应该是泛型的类型推断机制造成的,对于copy2方法,虽然你传入的两个参数类型不一致,
但是泛型的这 ...

按你所说:ArrayList应该接受Object类型的数据,接受其他类型就是不匹配了吧?  那么copy1(new ArrayList<String>(),new String[]{});ArrayList接收一个String类型的怎么不报错呢?????还请同学解答我的疑问
回复 使用道具 举报
李敬卫 发表于 2013-1-23 23:02
按你所说:ArrayList应该接受Object类型的数据,接受其他类型就是不匹配了吧?  那么copy1(new ArrayList( ...

public static <T> void  copy1(Collection<T> des,T[] src){
}
因为你如果改成String的话编译器就推断出T的类型是String了,类型是匹配的当然不报错了啊
回复 使用道具 举报
本帖最后由 黑马张英涛 于 2013-1-24 09:02 编辑

public static <T1> void  copy1(Collection<T2> des,T3[] src){
}
为了便于理解我们给3个T都加上标号。
当对方法进行编译时,编译器会先看T2跟T3是否类型一致,一致的话T1就是该类型,
(注意看的是你给他传递的T类型,而不是T[] 类型)
如果不一致的话就会看T2的父类是否跟T3一致(具体顺序是先T2还是先T3不知道),
一致的话T1就是T3类型的,然后会把T2也认为是T3类型(只是编译的时候这样判定,实际上运行时还是自己指定的类型)
如果还不一致的话就继续往上推断,一直到出现一致类型
推断到最后是找一个公共类型而不一定是Object类,张老师的视频讲过类似的例子:
         public static void main(String[] args) {               
                Number num1=add(1.1,3);         //编译通过  
                Object num2=add(1.1,3);          //编译也通过,(这种机制个人感觉就好像在找一个最小公倍数)
                Object num3=add(1.1,"abc");   //编译也通过
        }        
        public static <T> T add(T x,T y){
                return y;
        }

改为String类型的话T2 T3都是String,T1当然也是String了,跟T2是一致的,所以编译通过


评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

回复 使用道具 举报
泛型技术,是用来将一些运行时可能出现的异常,在编译时期就会有相应的提示,一旦传入不符的类型直接编译错误,不生成类文件。

评分

参与人数 1技术分 +1 收起 理由
冯海霞 + 1

查看全部评分

回复 使用道具 举报
谢洋 高级黑马 2013-1-26 23:25:34
7#
其实,泛型是应用在编译时期的泛型类型限定作检查,编译后会把泛型类型信息去掉。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马