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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 庄星睿 中级黑马   /  2012-6-15 21:59  /  3548 人查看  /  8 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

关于泛型里的疑问:
  1. import java.util.*;
  2. class GenericDemo6
  3. {
  4. public static void main(String[] args)
  5. {
  6. ArrayList<Person> p=new ArrayList<Person>();
  7. p.add(new Person("abc"));
  8. p.add(new Person("abcd"));
  9. p.add(new Person("abcde"));

  10. ArrayList<Student> s=new ArrayList<Student>();
  11. s.add(new Student("s----abc"));
  12. s.add(new Student("s----abcd"));
  13. s.add(new Student("s-----abcde"));
  14. print(p);

  15. }
  16. //public static void print(ArrayList<? extends Person> al)
  17. public static void print(ArrayList<? super Student> al)  //视频里说的是限定下限,可以接收他或他的父类
  18. {
  19. //Iterator<? extends Person> it=al.iterator();
  20. Iterator<? super Student> it=al.iterator(); // 这里也是
  21. while(it.hasNext())
  22. {
  23. System.out.println(it.next().getName());
  24. }

  25. }
  26. }


  27. class Person
  28. {
  29. private String name;
  30. public Person(String name)
  31. {
  32. this.name=name;
  33. }

  34. public String getName()
  35. {
  36. return name;
  37. }
  38. }

  39. class Student extends Person
  40. {
  41. private String name;
  42. public Student(String name)
  43. {
  44. super(name);
  45. }

  46. }
复制代码
这里<? super Stduent>既可以接收Student ,和Person这两个父类,那Object也是他们的父类,肯定是不能接收的,因为没有getName()方法,那就是只能接收Person 和Student了,但这两个我都试了一下都是编译败:
GenericDemo6.java:38: 错误: 找不到符号
                        System.out.println(it.next().getName());
                                                    ^
  符号:   方法 getName()
  位置: 类 Object
1 个错误

评分

参与人数 1技术分 +1 收起 理由
黄奕豪 + 1 赞一个!

查看全部评分

8 个回复

倒序浏览
你自定义的Person和Student中应该加入你需要的类getName(),否则肯定会报错的,因为范型方法中用到了这个方法,而你却没有定义
回复 使用道具 举报
19.public static void print(ArrayList<? super Student> al)

这句代码的泛型意思是:ArrayList中只能存储Student及其它的父类。。。这一点没有错。。

但是在迭代的过程中。。要想用方法那么只能用其最顶层超类的方法。。这意味着只能用Object中的方法。。

你可以想象一下。。只有Object中的方法才能满足所有其子类都拥有。。

比如你在迭代中用toString()、hashCode()等Object中的方法是不会报错的。。

点评

说的好 泛型的下限限定了只能传该类及该类的父类,并没有限定他的方法。但事实是:自此只能用Object类中有的方法,可以这样理解吗?  发表于 2015-2-1 15:31

评分

参与人数 1技术分 +1 收起 理由
黄奕豪 + 1 赞一个!

查看全部评分

回复 使用道具 举报
张老师在讲泛型的时候讲到,使用?通配符可以引用其他各种参数化的类型。?通配符定义的变量主要用作引用,可以调用与参数化无关的方法,不能调用与参数化有关的方法。
因为it.next()返回的确实是Student的父类,但是Student的父类难道就一定是Person吗?还可以是Person的父类啊,或者Person父类的父类,一直到Object,他们会拥有getName方法吗?显然是不可能的,这里你可以在it.next()前面加强转,( (Person) it.next()).getName(),这样编译就不会出错了!
回复 使用道具 举报
李盼 发表于 2012-6-15 22:33
张老师在讲泛型的时候讲到,使用?通配符可以引用其他各种参数化的类型。?通配符定义的变量主要用作引用, ...

这里强转也不合适吧。。如果正的存入的是Object。。那你把他转成Person。。不行吧?
回复 使用道具 举报
梁清平 发表于 2012-6-15 22:38
这里强转也不合适吧。。如果正的存入的是Object。。那你把他转成Person。。不行吧? ...

强转可以骗过编译器,但是如果你最终存放的既不是Person,也不是Student,而那个对象也没有getName方法,执行也会报错!如果你存的是Person和Student或者其他有getName的方法并且是Student父类的对象,就没问题了!
回复 使用道具 举报
李盼 发表于 2012-6-15 22:43
强转可以骗过编译器,但是如果你最终存放的既不是Person,也不是Student,而那个对象也没有getName方法, ...

哦。。。这样做就没意义了。。如果是这样。。就干脆把泛型定义成<Person>算了。。。泛型要解决的问题之一也正是对象强转的问题。。
回复 使用道具 举报
和我的问题一样啊 没想到啊 你现在解决了吗?我现在还没有,求解释,谢谢额!!!http://bbs.itheima.com/thread-168369-1-1.html
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马