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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 汉谟拉比 中级黑马   /  2014-7-7 16:31  /  1931 人查看  /  11 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

import java.util.*;
class Person
{
        private String name;
        Person(String name)
        {
                this.name = name;
        }
        public String getName()
        {
                return name;
        }
}
class Student extends Person
{
        Student(String name)
        {
                super(name);
        }       
}
class FanxingDemo1
{
        public static void main(String[] args)
        {
                ArrayList<Person> a1 = new ArrayList<Person>();
                a1.add(new Person("zhangsan"));
                a1.add(new Person("zhnsagk"));
                a1.add(new Person("lisi"));
                a1.add(new Person("werrda"));
                ArrayList<Student> a2 = new ArrayList<Student>();
                a2.add(new Student("xuesheng1..."));
                a2.add(new Student("xuesheng2..."));
                a2.add(new Student("xuesheng3..."));
                a2.add(new Student("xuesheng4..."));
                sop(a1);
        }
        public static void sop(ArrayList<? super Student> a)
        {
                Iterator<? super Student> i = a.iterator();
                while(i.hasNext())
                {
                        //System.out.println(i.next());
                        System.out.println(i.next().getName());
                }
        }
}
为什么最后访问不到Person类里面的getName()方法吗,,,诧异呀,,,谁来破解一些,,,我是小白呀

11 个回复

倒序浏览
我想练习一下泛型应用,,,这个怎么就不行了呢
回复 使用道具 举报
如果将<? super Student>改成<? extends Person>则完全正常运行呀,,求解
回复 使用道具 举报
木有人进来呀:'(
回复 使用道具 举报
转换一下就ok了.为什么要转换我也不打清楚,估计是因为通配符
Person p = (Person) i.next();                         
System.out.println( p.getName());

System.out.println(((Person) i.next()).getName());
回复 使用道具 举报
的确。强转之后可以,但是不太明白什么原理呀,,,
回复 使用道具 举报
本帖最后由 EarlyHeart 于 2014-7-8 03:06 编辑

不清楚楼主对泛型通配符了解的多不,所以多写了一些,如果了解,无视第1点,直接看第2点,楼主的问题主要在第2点说明。
1.ArrayList<? super Student>限制ArrayList<T>中的T属于? "super Student"的范围(Student及其父类),也就是说我们在给ArrayList<? super Student>的变量赋值时只能赋泛型为Student及其父类的ArrayList对象,如代码:
  1. public class Demo7 {
  2.         public static void main(String[] args) {
  3.                 ArrayList<? super A> list = new ArrayList<A>();//A属于"A及A的父类"这个范围内故编译成功
  4.                 ArrayList<? super A> list1 = new ArrayList<Object>();//Object也为A的父类故编译成功
  5.                 ArrayList<? super A> list2 = new ArrayList<B>();//B是A的子类,不属于"A及A的父类"这个父类故编译失败
  6.         }
  7. }
  8. class A{}
  9. class B extends A{}
复制代码

ArrayList<? extends A>同理,只不过“? extends A”表示的是A及A的子类
2.楼主的代码中的问题在于:
  1. public static void sop(ArrayList<? super Student> a)
  2.      {
  3.              Iterator<? super Student> i = a.iterator();//注意这里引用变量i代表的是一个包含元素属于"? super Student"范围的Iterator,
  4.                                                                                                      //而这个变量i并不知道自己包含的元素是哪个类型的(他只是知道这个类型的一个范围而已),
  5.                                                                                                      //那么万一这个i所指对象里面放的是一堆Object怎么办呢(也就是如果 a.iterator()返回的是一个Iterator(Object)),
  6.                                                                                                      //很明显Object没有你定义的getName()方法,所以,这里为了以后运行时的安全,i。next()返回的是"? super Student"
  7.                                                                                                      //这个范围的上界,即Object对象,所以便没有我们自己定义的getName()方法。
  8.              while(i.hasNext())
  9.              {
  10.                      //System.out.println(i.next());
  11.                          System.out.println(i.next().getName());
  12.              }
  13.      }
  14.          /*
  15.      public static void sop(ArrayList<? extends Person> a)
  16.      {
  17.              Iterator<? extends Person> i = a.iterator();//而这里"? extends Person"代表的是Person及其子类,而无论Person还是它的子类都有我们自己定义的getName()方法,
  18.                                                                                                      //所以这个范围内的任何类型具备getName方法(实际上这里a.iterator()返回的是Iterator<Person>,依旧去了上界),因此
  19.                                                                                                       //可以编译通过。
  20.              while(i.hasNext())
  21.              {
  22.                      //System.out.println(i.next());
  23.                          System.out.println(i.next().getName());
  24.              }
  25.      }
  26.      */
复制代码
回复 使用道具 举报
楼上解释相当精辟!
回复 使用道具 举报
7#解释的相当靠谱
回复 使用道具 举报
学习了,哈哈
回复 使用道具 举报
楼上解释得很清楚
回复 使用道具 举报
谢谢EarlyHeart哦,,,学习了
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马