� FEIT EDUCATION '6��.Q:� 22s2 - INFO1113 期末复习 Part 2 by Shirley老师 Generics 泛型 泛型的目的是提供编译时类型安全检测, 将数据类型传给泛型方法。它的好处是可以 在同一个结构上使用不同的数据类型。 泛型的声明 所有泛型方法声明都有一个类型参数声明部分,例如
,用于传递数据类型。 声明的位置在方法返回类型之前,例如: public static void method(T input){ 每一个类型参数声明部分包含一个或多个类型参数,例如不只是, 也可以是 里面的字符 T被称为 Type parameter类型参数. 这些参数会在编译时一一对应到在代码 中使用的位置. 这个字母可以是任何字母,但有一些约定俗成的习惯,例如: 如果只有一个 type parameter,一般用 T表示 type。 如果这个 type parameter用于合集里,则用 E来表示 Element。 如果有多个 type parameter, 想表达的是 Key与 Value,用 K和 V来表示,等等 泛型可以用于泛型方法和泛型类。 泛型方法 在以下这个例子里,返回值是 void. 这个类型参数需要写在返回值前面,此 时才可以在方法中使用泛型类型 T。 例子:在集合里找东西并打印。 public static void findAndPrintItem(T item, T[] stuff){ for (T t: stuff){ if (t.equals(item)){ System.out.println(t); break; } } System.out.println("Can't find it"); } 泛型类 泛型类的声明是在 class的名字后面加上类型参数 public class Node { //key这个成员变量的类型为 T,T的类型由外部指定 private T key; private Node next; public Node(T key) { //泛型 Constructor, key的类型也为 T,T的类型由外部指定 this.key = key; } public T getKey() { //泛型方法 getKey的返回值类型为 T,T的类型由外部指定 return key; } public void setNext(Node next) { this.next = next; } } public class GenericLinkedList { private Node head = null; public void AddFront(Node front) { front.setNext(this.head); this.head = front; } public static void main(String[] args) { var list = new GenericLinkedList(); list.AddFront(new Node(1)); System.out.println(list.head.getKey()); } } 限制泛型的使用范围 public class LinkedList { 通过 LinkedList这个 class的 类只能是 ParentClass的子类。 但即使如此,在编译结束以后,每一个 class分别使用的类型都会确定下来。子类之间 也是不可以混用的。 比如即使我们规定 List, Car和 Truck都是 Vehicle的子类,声明的时 候确定了是 List, List的两个 list object,这两个 list之间也不能再互相加对 方的类。 泛型的限制 1. 不可以在 generics里使用 primitive type 一直以来我们都知道 collections(比如 arraylist,linkedlist,hashmap)里,只能用 reference type,例如大写的 Integer,但不可以用小写的 int。其原因是 Generics的 type parameter规定了这个输入的 type不可以是 primitive type。它可以是任何数据类 型,包括 object,array,interface,甚至是另一个 type variable。 2. 如果使用了泛型,就不能在方法内部 cast数据或者判断数据的类型。这个的原因 是 Java编译器会在编译的时候抹除所有的 generic parameter。不可以通过 instance of 来判断具体到底是哪一种数据被作为 parameter传进方法里了。 例如: public static void example(List list) { if (list instanceof ArrayList) { // compile-time error // ... } } 这里就会出现 compile time error。 Final 真题 选择 Given the following definitions, which assignments are legal? class Box{} class SuperBox extends Box{} I. Box