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

本帖最后由 黑马朱超 于 2013-3-28 23:45 编辑

代码一:采用上限
  1. /**
  2. javaSE day15-12泛型限定
  3. */
  4. import java.util.*;
  5. class GenericDemo7
  6. {
  7.         public static void main(String[] args)
  8.         {

  9.                 ArrayList<Person> al = new ArrayList<Person>();
  10.                 al.add(new Person("abc1"));
  11.                 al.add(new Person("abc2"));
  12.                 al.add(new Person("abc3"));
  13.                 printColl(al);

  14.                 ArrayList<Student> all = new ArrayList<Student>();
  15.                 all.add(new Student("abc---1"));
  16.                 all.add(new Student("abc--2"));
  17.                 all.add(new Student("abc--3"));
  18.                 printColl(all);//ArrayList<Person> al = ArrayList<Student>();error

  19.         }        

  20.         public static void printColl(ArrayList<? extends Person> al)//采用泛型限定上限
  21.         {
  22.                 Iterator<? extends Person> it = al.iterator();
  23.                 while(it.hasNext())
  24.                 {
  25.                         System.out.println(it.next().getName());
  26.                 }
  27.         }
  28. }
  29. class Person
  30. {
  31.         private String name;
  32.         Person(String name)
  33.         {
  34.                 this.name = name;
  35.         }
  36.         public String getName()
  37.         {
  38.                 return name;
  39.         }
  40. }
  41. class Student extends Person
  42. {
  43.         Student(String name)
  44.         {
  45.                 super(name);
  46.         }
  47. }
复制代码
编译运行OK

代码二:采用下限
  1. /**
  2. javaSE day15-12泛型限定
  3. */
  4. import java.util.*;
  5. class GenericDemo7
  6. {
  7.         public static void main(String[] args)
  8.         {

  9.                 ArrayList<Person> al = new ArrayList<Person>();
  10.                 al.add(new Person("abc1"));
  11.                 al.add(new Person("abc2"));
  12.                 al.add(new Person("abc3"));
  13.                 printColl(al);

  14.                 ArrayList<Student> all = new ArrayList<Student>();
  15.                 all.add(new Student("abc---1"));
  16.                 all.add(new Student("abc--2"));
  17.                 all.add(new Student("abc--3"));
  18.                 printColl(all);//ArrayList<Person> al = ArrayList<Student>();error

  19.         }        //指向和接收左右两边要一致

  20.         public static void printColl(ArrayList<? super Student> al)//采用泛型限定下限
  21.         {
  22.                 Iterator<? super Student> it = al.iterator();
  23.                 while(it.hasNext())
  24.                 {
  25.                         System.out.println(it.next().getName());
  26.                 }
  27.         }
  28. }
  29. class Person
  30. {
  31.         private String name;
  32.         Person(String name)
  33.         {
  34.                 this.name = name;
  35.         }
  36.         public String getName()
  37.         {
  38.                 return name;
  39.         }
  40. }
  41. class Student extends Person
  42. {
  43.         Student(String name)
  44.         {
  45.                 super(name);
  46.         }
  47. }
复制代码
编译说找不到符号


按道理来说的话,按照上限来和按照下限来的效果一样啊。因为Student类继承了getName()的方法啊,但是为什么会报错呢,明明定义的时候的类型限定了啊,为什么它要把子类转换成超类Object呢,就是因为Person或者是Student类被super成了Object,所以它找不到getName()方法。。。。
有什么解决方法么?
求达人解析

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1

查看全部评分

4 个回复

倒序浏览
个人理解:下限的情况下:如果是把结果强转为Person,当我们传入的Object,那就会l转换失败,如果转为Object,就不会,但只能用Object的方法。
当要反射出某个泛型方法,我们传进入参数也是Object,这也说明编译后,应用了泛型的地方通常是被编译成Object,以适应传入的各种子类实参;这也是为什么基本数据类型(没继承Object)为什么能作为泛型参数原吧

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1

查看全部评分

回复 使用道具 举报
看了一些资料,我的理解是:对于一个集合中,能装入父类的,一定可以装入子类,而相反则不一定。所以你这里用? super Student,其中的通配符?是不确定的,即使你下面已经将Student继承了Person,但是抛开这个来说,?其实是不确定的。所以,在Interator使用这个,它可能就无法获悉Student中会得到Person的方法,所以,它认为是找不到这个方法的。
建议你看看这篇文章:http://hi.baidu.com/augustus_blog/item/d9331b3469b65a1d9dc65e69

评分

参与人数 1技术分 +1 收起 理由
陈丽莉 + 1

查看全部评分

回复 使用道具 举报
小黑黑 发表于 2013-3-26 13:23
看了一些资料,我的理解是:对于一个集合中,能装入父类的,一定可以装入子类,而相反则不一定。所以你这里 ...

迭代器没有必要要获悉那个方法吧,只要知道是那个Person类的对象或者是Student的对象就可以了吧。Interator it = al.interator();后
it.hasNext();it.next()输出的元素是类的对象的地址,通过地址找到对象去调用getName();
我看了那篇文章,感觉没有看懂。呵呵
回复 使用道具 举报
谢洋 发表于 2013-3-26 12:35
个人理解:下限的情况下:如果是把结果强转为Person,当我们传入的Object,那就会l转换失败,如果转为Objec ...

恩,编译失败的原因我也觉得应该是这个泛型下限包括了超类Object,如果是Object的话,就调用不了那个方法,因此在编译的时候就给出提醒.报错的初衷应该是给出提醒,不是我们给定的Student,Person类的问题.
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马