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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© HM朱蛟 高级黑马   /  2013-4-5 02:36  /  1821 人查看  /  14 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

本帖最后由 HM朱蛟 于 2013-4-5 06:01 编辑


该代码报错,说找不到getName方法。
C:\Documents and Settings\Administrator\桌面\BH-temp>javac GenericXD.java
GenericXD.java:47: 找不到符号
符号: 方法 getName()
位置: 类 java.lang.Object
                        System.out.println(it.next().getName());
                                                    ^
1 错误
  1. import java.util.*;

  2. class Demo
  3. {
  4.         public static void main(String[] args)
  5.         {
  6.                 ArrayList<Person> al = new ArrayList<Person>();
  7.                 al.add(new Person("NAME--01"));
  8.     al.add(new Person("NAME--02"));
  9.     al.add(new Person("NAME--03"));
  10.                
  11.           ArrayList<Student> al1 = new ArrayList<Student>();
  12.                 al1.add(new Student("NAME-stu--04"));
  13.     al1.add(new Student("NAME-stu--05"));
  14.     al1.add(new Student("NAME-stu--06"));
  15.                
  16.                 print(al1);//传入点 Student   ArrayList<Person> al = new ArrayList<Student>(); //::Error::若成立,则可以存工人                        
  17.         }

  18.         public static void print(ArrayList<? super Student> al)//这句为何报错? 不是说支持Student和其父类的么?
  19.         //public static void print(ArrayList<? extends Person> al)//泛型限定,上限,支持Person和Person的子类
  20.         {
  21.          Iterator<? super Student> it = al.iterator();        
  22.          
  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.         
  37.         public String getName()
  38.         {
  39.                 return name;        
  40.         }
  41. }

  42. class Student extends Person
  43. {
  44.         Student (String name)
  45.         {
  46.                 super(name);
  47.         }
  48. }
复制代码

评分

参与人数 1技术分 +1 收起 理由
张熙韬 + 1

查看全部评分

14 个回复

倒序浏览
  1. public static void print(ArrayList<? super Student> al)//这句为何报错? 不是说支持Student和其父类的么?
  2.         //public static void print(ArrayList<? extends Person> al)//泛型限定,上限,支持Person和Person的子类
  3.         {
  4.          Iterator<? super Student> it = al.iterator();        
  5.          
  6.                 while(it.hasNext())
  7.                 {
  8.                        //System.out.println(it.next().getName());这里不能直接调用getName方法,因为不知道it.next的返回类型。
  9.                         
  10.                         Student s = (Student)it.next();//先把it.next返回的结果转换为学生对象,然后通过学生对象调用getName方法。
  11.                         System.out.println(s.getName());   
  12.                 }
  13.         }
复制代码

评分

参与人数 1技术分 +1 收起 理由
张熙韬 + 1

查看全部评分

回复 使用道具 举报
  1. while (it.hasNext()) {
  2.                        
  3.                         System.out.println(((Person)it.next()).getName());
  4.                 }
复制代码
测试通过
回复 使用道具 举报
程媛媛 发表于 2013-4-5 02:53

ArrayList<? super Student> al    视频上说这个声明就是说传入的对象可以是Student和Student的父类
泛型不是可以避免强转为何还要用强转呢?
用这句没强转也没报错:public static void print(ArrayList<? extends Person> al)

我觉得 ArrayList<? super Student> al  和 ArrayList<? extends Person> al) 应该是相同效果

求解

回复 使用道具 举报
代码最后  Student extends Person   
相当于 Person
            ———>Student
(ArrayList<? extends Person> al)     
相当于 Person
          ———> Student
          ———>ArrayList    有可能和Student是平级,也有可能是Student的子集   这时  你再写下面一句,编译器就无法判断这两种情况  所以就报错!
(ArrayList<? super Student> al)
回复 使用道具 举报
HM朱蛟 发表于 2013-4-5 03:01
ArrayList

如果是这样的ArrayList<Student>写法,就不需要强转,<? super Student> 并不是明确指定是哪一个类型,如果getName是子类特有的方法,你传了一个Person类的对象,那么Person就不能调用getName.所以定义泛型时,要明确指定是哪个类型。
回复 使用道具 举报
陈腾跃_2013 发表于 2013-4-5 02:58
测试通过

谢谢 谢谢
回复 使用道具 举报
郝勇 发表于 2013-4-5 03:11
代码最后  Student extends Person   
相当于 Person
            ———>Student

谢谢  但是哥们 我没看懂你的思路啊  对泛型我理解的比较浅
ArrayList<? super Student> al  和 ArrayList<? extends Person> al)  这两句为何一个要强转一个不需要强转呢?

为何这段代码不用强转呢?
  1. import java.util.*;

  2. class Demo
  3. {
  4.         public static void main(String[] args)
  5.         {
  6.                                         ArrayList<Person> al = new ArrayList<Person>();
  7.                                                 al.add(new Person("NAME--01"));
  8.                                                 al.add(new Person("NAME--02"));
  9.                                                 al.add(new Person("NAME--03"));
  10.                
  11.                       ArrayList<Student> al1 = new ArrayList<Student>();
  12.                         al1.add(new Student("NAME-stu--04"));
  13.                                     al1.add(new Student("NAME-stu--05"));
  14.                                     al1.add(new Student("NAME-stu--06"));
  15.                
  16.           print(al1);                    
  17.         }

  18.        public static void print(ArrayList<? extends Person> al)//为何改成这样不用强转呢?
  19.                    {
  20.                                    Iterator<? extends Person> it = al.iterator();   
  21.                     
  22.                             while(it.hasNext())
  23.                             {
  24.                                                 System.out.println(it.next().getName());      
  25.                             }
  26.                    }
  27. }

  28. class Person
  29. {
  30.         private String name;
  31.         Person(String name)
  32.         {
  33.           this.name = name;        
  34.         }
  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. }
复制代码
回复 使用道具 举报
程媛媛 发表于 2013-4-5 03:21
如果是这样的ArrayList写法,就不需要强转,

非常感谢你的指点  说的有道理
哥们儿还有一点不明白 就是我7楼贴的代码
20行我是定义成这个的public static void print(ArrayList<? extends Person> al)
照理说 这样<? extends Person>也不算是 定义了具体的类型啊
为什么它不用强转就可以编译和运行了呢?有点费解...
回复 使用道具 举报
HM朱蛟 发表于 2013-4-5 03:35
非常感谢你的指点  说的有道理
哥们儿还有一点不明白 就是我7楼贴的代码
20行我是定义成这个的public st ...

我试了一下确实可以通过,只能通过父类有的方法,如果在子类中定义一个特有的方法,调用子类特有的方法,也是不能通过的。建议在使用上限或者下限的时候还是转换一下比较好。
回复 使用道具 举报
程媛媛 发表于 2013-4-5 17:25
我试了一下确实可以通过,只能通过父类有的方法,如果在子类中定义一个特有的方法,调用子类特有的方法, ...

恩 谢谢了啊
回复 使用道具 举报
程媛媛 发表于 2013-4-5 17:25
我试了一下确实可以通过,只能通过父类有的方法,如果在子类中定义一个特有的方法,调用子类特有的方法, ...

我准备不再纠结这个问题了  我觉得这事自找麻烦了  从昨晚到现在  
回复 使用道具 举报
HM朱蛟 发表于 2013-4-5 17:29
我准备不再纠结这个问题了  我觉得这事自找麻烦了  从昨晚到现在

对,有的时候不必太较真了。呵呵。
回复 使用道具 举报
程媛媛 发表于 2013-4-5 17:32
对,有的时候不必太较真了。呵呵。

我自己总结了一点想法 但是我也不知道对不对  你帮我看看吧

对于之上的问题我最先是这样思考的:

上限分析:
public static void print(ArrayList<? extends Person> al)
含义:可以接收Person以及Person的子类。
分析:那么换种角度想,Person是父类,不管他有多少个子类,只要是Person的父类,那么这些子类必定拥有父类的方法,在这里是getName()。


下限分析:
public static void print(ArrayList <? super Student> al)
含义:可以接收Student以及Student的父类。
分析:我最初的想法是,Person有getName()方法,所以Student也应该有getName()方法,但是我忽略了一点,即是Student的父类不止Person一个,下限是向上扩展,也就是说Student有可能继承其他的父类,这些父类里或许有getName()或许没有,那么换句话说,Student类有可能不具备getName()方法。所以程序会报错找不到getName()方法。所以在这里需要进行强转成Person才能让虚拟机明确,”哦,原来是Person的子类,他具备getName()方法,编译通过”。

但是总感觉哪里不对,有待思考。。。
回复 使用道具 举报
HM朱蛟 发表于 2013-4-5 17:41
我自己总结了一点想法 但是我也不知道对不对  你帮我看看吧

对于之上的问题我最先是这样思考的:

可以先这样理解,或许通过以后的不断学习、应用,就可以想通了。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马