任何一个泛型类型,都对应这个一个原始类型。原始类型的名字来源于带参数的泛型类型名去掉参数后的结果,并将类中用到类型变量的地方替换为类型变量的限定类型(如果没有限定类型就用Object)。下面是一个来源于《Java核心技术 卷1》的例子:
类型擦除前:
package generic; /** * @version 1.00 2004-05-10 * @author Cay Horstmann */ public class Pair<T> { private T first; private T second; public Pair() { first = null; second = null; } public Pair(T first, T second) { this.first = first; this.second = second; } public T getFirst() { return first; } public T getSecond() { return second; } public void setFirst(T newValue) { first = newValue; } public void setSecond(T newValue) { second = newValue; } }
类型擦除后:
package generic; /** * pair<T>类型擦出后的版本,即pair<T>得原始类型; * 擦除规则是,删除类名后面的类型变量,并将类中用到 * 类型变量的地方替换为类型变量的限定类型( * 如果没有限定类型就用Object) * @author yuncong * */ public class Pair { private Object first; private Object second; public PairOrigin() { first = null; second = null; } public PairOrigin(Object first, Object second) { this.first = first; this.second = second; } public Object getFirst() { return first; } public Object getSecond() { return second; } public void setFirst(Object newValue) { first = newValue; } public void setSecond(Object newValue) { second = newValue; } }
针对泛型类的测试,有两个辅助类:
package generic; public class Person extends Animal { private String name; public Person(String name) { super(); this.name = name; } public String getName() { return name; } public void setName(String name) { this.name = name; } @Override public String toString() { return "Person [name=" + name + "]"; } }
package generic; public class Student extends Person { private String studentNumber; public Student(String name, String registrationNumber) { super(name); this.studentNumber = registrationNumber; } public String getStudentNumber() { return studentNumber; } public void setStudentNumber(String studentNumber) { this.studentNumber = studentNumber; } @Override public String toString() { return "Student [studentNumber=" + studentNumber + ", name=" + getName() + "]"; } }
下面的测试说明了调用Pair<T>的getFirst()方法的实际过程:
package generic; public class Test3 { public static void main(String[] args) { Pair<Person> pair = new Pair<Person>(new Person("li"), new Person("wang")); /** * 因为Pair<T>在类型擦除之后,它的 * getFirst()方法返回类型其实是Object, * 所以这里其实经历了两步: * 1.对原始方法pair.getFirst()的调用 * 2.将返回的Object类型强制转化为Person类型 */ Person person = pair.getFirst(); /** * 关于上面这个测试,下面的知识是必须明白的 */ // 将父类型赋值给为子类型,必须需要强制类型转化 Person person2 = new Person("yuncong"); Person person3 = new Student("yuncong", "1"); Student student = (Student) person3;// ok // 如果父类型的实际类型不是子类型,就会报造型错误 Student student1 = (Student) person2;// error } }
下面的测试说明参数化类型是它的原始类型的子类型:
package generic; public class Test4 { public static void main(String[] args) { Pair<Person> personPair = new Pair<Person>(); // 可以将参数化类型转化为它的原始类型 Pair pair = personPair; Building building = new Building("dingxin"); /** * ok, 可以将building传给pair; * 失去了泛型程序设计提供的附加安全性(类型检查) */ pair.setFirst(building); Person person = (Person) pair.getFirst(); // 造型错误 /** * The method setFirst(Person) in the type Pair<Person> * is not applicable for the arguments (Building) */ // error,不能将building传给personPair,泛型程序设计提供的类型安全 personPair.setFirst(building); } }
时间: 2024-10-06 03:19:26