黑马程序员技术交流社区

标题: 泛型的问题。 [打印本页]

作者: 沈文杰    时间: 2013-2-4 16:09
标题: 泛型的问题。
本帖最后由 张向辉 于 2013-2-6 15:03 编辑

class Student implements Comparable<Student>   
这一句话为什么一定呀加泛型不然就会出问题?

/*
2013年1月8日20:58:33(HashMapTest)
1、描述学生对象,将学生对象封装成类。
2、定义HashMap容器,将学生对象作为键,地址作为值。存入集合中
3、获取HashMap集合中的元素。
*/
import java.util.*;
class Student implements Comparable<Student>   
{
  private String name;
  private int age;
  
  Student(String name,int age)
  {
    this.name = name;
    this.age = age;
  }
  
  public String getName()
  {
    return name;
  }
  
  public int getAge()
  {
    return age;
  }
  
  public int hashCode()
  {
    return name.hashCode()+age*34;
  }
  
  public boolean equals(Object obj)
  {
    if(!(obj instanceof Student))
    throw new ClassCastException("非法类型输入");
   
    Student stu = (Student)obj;
   
    return this.name.equals(stu.name) &&this.age==stu.age;
  }
  
  public int compareTo(Student s)
  {
    int num = new Integer(this.age).compareTo(s.age);
   
    if(num==0)
    return this.name.compareTo(s.name);
   
    return num;
  }
  
  public String toString()
  {
    return name+":"+age;
  }
  
}
class HashMapTest
{
  public static void main(String[] args)
  {
    HashMap<Student,String> hm = new HashMap<Student,String>();
    hm.put(new Student("zhangsan1",20),"beijing");
    hm.put(new Student("zhangsan5",21),"tianjin");
    hm.put(new Student("zhangsan2",23),"nanjin");
    hm.put(new Student("zhangsan1",20),"dongjin");
   
         //使用entrySet方法取出
     
     Set<Map.Entry<Student,String>> entryset = hm.entrySet();
     Iterator<Map.Entry<Student,String>> it = entryset.iterator();
     
     while(it.hasNext())
     {
       Map.Entry<Student,String> me = it.next();
       Student s = me.getKey();
       String addr = me.getValue();
      
       sop("Student="+s+",addr="+addr);
     }
     
  }
  
  public static void sop(Object obj)
  {
    System.out.println(obj);
  }
}


作者: 李洪因    时间: 2013-2-4 16:25
Java中的泛型基本上都是在编译器这个层次来实现的。在生成的Java字节代码中是不包含泛型中的类型信息的。使用泛型的时候加上的类型参数,会被编译器在编译的时候去掉,这个过程就称为类型擦除。
泛型的类型参数不能用在Java异常处理的catch语句中。因为异常处理是由JVM在运行时刻来进行的。由于类型信息被擦除,JVM是无法区分两个异常类型MyException<String>和MyException<Integer>的。对于JVM来说,它们都是 MyException类型的。也就无法执行与异常对应的catch语句。
类型擦除的基本过程也比较简单,首先是找到用来替换类型参数的具体类。这个具体类一般是Object。如果指定了类型参数的上界的话,则使用这个上界。把代码中的类型参数都替换成具体的类。同时去掉出现的类型声明,即去掉<>的内容。比如T get()方法声明就变成了Object get();List<String>就变成了List。接下来就可能需要生成一些桥接方法(bridge method)。这是由于擦除了类型之后的类可能缺少某些必须的方法。比如你的代码:

class Student implements Comparable<Student>    {
  private String name;
  private int age;
  
  Student(String name,int age)
  {
    this.name = name;
    this.age = age;
  }
..................  
当类型信息被擦除之后,上述类的声明变成了class Student  implements Comparable。但是这样的话,类MyString就会有编译错误,因为没有实现接口Comparable声明的int compareTo(Object)方法。这个时候就由编译器来动态生成这个方法。
作者: 沈文杰    时间: 2013-2-4 16:43
看了两遍没看懂,只有先记下来,慢慢想了




欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) 黑马程序员IT技术论坛 X3.2