黑马程序员技术交流社区

标题: 泛型中,参数化类型与原始类型兼容的问题 [打印本页]

作者: librazeng    时间: 2013-5-29 15:42
标题: 泛型中,参数化类型与原始类型兼容的问题
这是黑马张健 同学提的问题:
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对象啊)。而如果两句合并为一句,肯定要报错,因为泛型是不存在继承关系的。因为平时我们看程序时,已经形成了运行程序代码的习惯,所以很容易产生误区。

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

作者: librazeng    时间: 2013-5-29 20:20
求大神回复~{:soso_e154:}
作者: 薛飞    时间: 2013-5-29 20:36
Vector v1 = new Vector<String>();  
Vector<Object> v = v1;
第二行编译器看到v1,嗯?这个v1没见过,不认识,这时它就向上找这个变量是否存在,如何存在。经编译器检查找到v1是一个引用变量,类型是Vector。这就O啦,符合编译器的语法要求,编译器就让它通过。即编译器认为v1是一个实例对象new Vector()。所以编译器认为这行实际是Vector<Object> v= new Vector();所以它不会报错。编译器就是检查一下语法是否符合规范,你要是把v1的泛型对象带进去,那就相当于在执行运行过程了
作者: 廖志强    时间: 2013-5-31 23:17
参数化类型与原始类型的兼容性:
参数化类型可以引用一个原始类型的对象,编译报告警告,例如, 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];

作者: librazeng    时间: 2013-6-1 07:52
廖志强 发表于 2013-5-31 23:17
参数化类型与原始类型的兼容性:
参数化类型可以引用一个原始类型的对象,编译报告警告,例如, Collection ...

参数化类型可以引用一个原始类型的对象,编译报告警告,例如, Collection<String> c = new Vector();//可不可以,不就是编译器一句话的事吗?
这句话是什么意思啊?




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