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

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

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

以下是我的思路,希望得到指点让我理顺这个泛型限定中的疑问。问题比较少就2个,但是表述能力欠缺,所以写了一大堆,见谅了。

代码目录:
Code1 是对上限的应用 :<? extends Person>
Code2 是对下限的应用 :<? extends Person> ,强转的情况下
Code3 是在指定了泛型的具体的类型后,便可以不用强转了
Code4 是比较器的例子


泛型的限定;
extends E: 可以接收E类型或者E的子类型。上限。
super E: 可以接收E类型或者E的父类型。下限
思考:
1:从Code1根据”? extends E: 可以接收E类型或者E的子类型。上限。”,我知道了Student是Person的子类,而public static void print(ArrayList<? extends Person> al)是接收Person以及Person的子类。所以用print(al1);的时候是可以将Student传入的。限定上限没问题,符合老师总结的使用规则。
2:从Code2根据”? super E: 可以接收E类型或者E的父类型。下限”,我知道了Student是Person的子类,而public static void print(ArrayList<? super Student> al)是接收Student及其Student的父类,但是编译报错说找不到getName()方法,于是经过分析和提问后,得到的答案是“<? super Student> 并不是明确指定是哪一个类型,如果getName是子类特有的方法,你传了一个Person类的对象,那么Person就不能调用getName.所以定义泛型时,要明确指定是哪个类型。


Q:第一个问题:
Code定义成这个的public static void print(ArrayList<? extends Person> al),照理说 这样<? extends Person>也不算是 定义了具体的类型,那么为什么它不用强转就可以编译和运行了呢?


3:指明了明确的类型后,不用强转了,这里就相当于没有使用泛型限定这一说,但是同时我验证了一下将这2句改成:public static void print(ArrayList<Person> al)和Iterator<Person> it = al.iterator();就如视频里所说,ArrayList<Person> al = new ArrayList<Student>,泛型类引用是不会自动类型提升的,也就是说必须2边一样。若又想保持类型不一样,又想让程序运行起来,那么就必须使用通配符和泛型限定,泛型限定为了在使用通配符的时候更安全。


Q:第二个问题:
Code4和 Code2/Code3 都是在使用<? super E>,下限应用,为何Code4可以不用强转也不用指明具体的子类类型,只需要指定父类类型就可以让程序运行?
我认为Code4的比较器例子才是真正意义上符合了泛型下限的使用规则,Code2和Code3要不就是强转,要不就是指明具体传入的那个类型。他们之间的区别究竟在何处呢?
  1. CODE 1

  2. import java.util.*;

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

  2. import java.util.*;

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

  19.         public static void print(ArrayList<? super Student> al)
  20.   {
  21.   Iterator<? super Student> it = al.iterator();        

  22.     while(it.hasNext())
  23.     {
  24.             Person p = (Person)it.next();//必须强转
  25.                         System.out.println(p.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. CODE 3:

  2. import java.util.*;

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

  2. import java.util.*;

  3. class GenericDemo7
  4. {
  5.         public static void main(String[] args)
  6.         {
  7.                 TreeSet<Student> ts = new TreeSet<Student>(new Comp());

  8.                 ts.add(new Student("abc03"));
  9.                 ts.add(new Student("abc02"));
  10.                 ts.add(new Student("abc06"));
  11.                 ts.add(new Student("abc01"));
  12.                
  13.                 Iterator<Student> it = ts.iterator();

  14.                 while(it.hasNext())
  15.                 {
  16.                         System.out.println(it.next().getName());
  17.                 }
  18. //-------------------------------------------------------------------------------
  19.                 TreeSet<Worker> ts1 = new TreeSet<Worker>(new Comp());

  20.                 ts1.add(new Worker("wabc--03"));
  21.                 ts1.add(new Worker("wabc--02"));
  22.                 ts1.add(new Worker("wabc--06"));
  23.                 ts1.add(new Worker("wabc--01"));

  24.                 Iterator<Worker> it1 = ts1.iterator();

  25.                 while(it1.hasNext())
  26.                 {
  27.                         System.out.println(it1.next().getName());
  28.                 }
  29.         }
  30. }

  31. class Comp implements Comparator<Person>
  32. {
  33.         public int compare(Person p1,Person p2)
  34.         {
  35.                 return p2.getName().compareTo(p1.getName());
  36.         }
  37. }

  38. class Person
  39. {
  40.         private String name;
  41.         Person(String name)
  42.         {
  43.                 this.name = name;
  44.         }
  45.         public String getName()
  46.         {
  47.                 return name;
  48.         }
  49.         public String toString()
  50.         {
  51.                 return "person :"+name;
  52.         }
  53. }

  54. class Student extends Person
  55. {
  56.         Student(String name)
  57.         {
  58.                 super(name);
  59.         }

  60. }

  61. class Worker extends Person
  62. {
  63.         Worker(String name)
  64.         {
  65.                 super(name);
  66.         }
  67. }
复制代码

5 个回复

倒序浏览
出门了 亲戚过生 吃完午饭回来看
回复 使用道具 举报
好长啊,我先酝酿一下
回复 使用道具 举报
张雪萍 发表于 2013-4-5 10:10
好长啊,我先酝酿一下

好的 谢谢 其实是我表述能力问题  表达好的可能三两句话就说明白了吧 但是我心理实在是纠结的已经尽力阐述问题了
回复 使用道具 举报
---- --------------------------------------  --------------------------------------  --------------------------------------  --------------------------------------  ----------------------------------
对于之上的问题我最先是这样思考的:

上限分析:
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()方法,编译通过”。

但是总感觉哪里不对,有待思考。。。
----- --------------------------------------  --------------------------------------  --------------------------------------  --------------------------------------  ---------------------------------
出门了  午饭后回来看
回复 使用道具 举报
我也在纠结下限。问题。
回复 使用道具 举报
您需要登录后才可以回帖 登录 | 加入黑马