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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

这是黑马张健 同学提的问题:
Vector<Object> v = new Vector<String>(); 编译器会报错误,因为参数化类型不考虑类型参数的继承关系。
但为什么这样写编译器就能通过呢?
Vector v1 = new Vector<String>();  
Vector<Object> v = v1;
有点不太明白,请高手解释一下原因。 谢谢!

回答:
李哲    泛型只是给编译器使用,但是编译器不知道v1包含什么元素,也就不会报错。(这个好理解,因为编译的时候还没有new对象,所以V1并没有指向new Vector<String>())
赵玮_Tom 编译过程只是严格检查语法。第一句编译不报错是因为没有参数化类型的引用可以接收参数化类型的实例(这个但根本上还是不明白),第二据编译不报错是因为对编译器而言,无参数化的变量也是可以赋值给参数化的变量的(这是为什么啊,比如Vector<String> v=new Vector();一个String类型的Vector凭什么可以指向没参数化的Vector对象啊)。而如果两句合并为一句,肯定要报错,因为泛型是不存在继承关系的。因为平时我们看程序时,已经形成了运行程序代码的习惯,所以很容易产生误区。

请高手做更进一步的解释,谢谢!

评分

参与人数 1技术分 +1 收起 理由
殇_心。 + 1

查看全部评分

4 个回复

倒序浏览
求大神回复~{:soso_e154:}
回复 使用道具 举报
Vector v1 = new Vector<String>();  
Vector<Object> v = v1;
第二行编译器看到v1,嗯?这个v1没见过,不认识,这时它就向上找这个变量是否存在,如何存在。经编译器检查找到v1是一个引用变量,类型是Vector。这就O啦,符合编译器的语法要求,编译器就让它通过。即编译器认为v1是一个实例对象new Vector()。所以编译器认为这行实际是Vector<Object> v= new Vector();所以它不会报错。编译器就是检查一下语法是否符合规范,你要是把v1的泛型对象带进去,那就相当于在执行运行过程了

评分

参与人数 1技术分 +1 收起 理由
袁梦希 + 1 很给力!

查看全部评分

回复 使用道具 举报
参数化类型与原始类型的兼容性:
参数化类型可以引用一个原始类型的对象,编译报告警告,例如, Collection<String> c = new Vector();//可不可以,不就是编译器一句话的事吗?
原始类型可以引用一个参数化类型的对象,编译报告警告,例如, Collection c = new Vector<String>();//原来的方法接受一个集合参数,新的类型也要能传进去




参数化类型不考虑类型参数的继承关系:
Vector<String> v = new Vector<Object>(); //错误!///不写<Object>没错,写了就是明知故犯
Vector<Object> v = new Vector<String>(); //也错误!




编译器不允许创建泛型变量的数组。即在创建数组实例时,数组的元素不能使用参数化的类型,例如,下面语句有错误:
  Vector<Integer> vectorList[] = new Vector<Integer>[10];

评分

参与人数 1技术分 +1 收起 理由
Sword + 1

查看全部评分

回复 使用道具 举报
廖志强 发表于 2013-5-31 23:17
参数化类型与原始类型的兼容性:
参数化类型可以引用一个原始类型的对象,编译报告警告,例如, Collection ...

参数化类型可以引用一个原始类型的对象,编译报告警告,例如, Collection<String> c = new Vector();//可不可以,不就是编译器一句话的事吗?
这句话是什么意思啊?
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马