java核心技术卷1——泛型

一、类型变量的限定

  • 表示T应该是绑定类型的子类型(subtype)。T和绑定类型可以是类,也可以是接口。
  • 一个类型变量或通配符可以有多个限定,例如T extends Comparable & Serializable,限定类型用“&”分隔,而逗号用来分隔类型变量。
  • 可以根据需要拥有多个接口超类型,但限定中至多有一个类。如果用一个类作为限定,它必须是限定列表中的第一个。
  • 为了提高效率,应该将标签(tagging)接口(即没有方法的接口)放在边界列表的末尾。

二、擦除

  • 原始类型用第一个限定的类型变量来替换,如果没有给定限定就用Object替换。例如,类Pair中的类型变量没有显式的限定。
  • 使用@SuppressWarnings("unchecked")或@SafeVarargs压制警告,由一个遗留的类得到一个原始类型的对象。可以将它赋给一个参数化的类型变量,当然,这样做会看到一个警告,例如:
    Dictionary labelTable = new JSlider().getLabelTable();

 三、泛型局限

  • 不能用基本类型实例化类型参数
  • 运行时类型查询只适用于原始类型
    • if (a instanceof Pair ) // ERROR
    • if (a instanceof Pair ) // ERROR
    • Pair  p = (Pair ) a; // WARNINC—can only test that a is a Pair
    • getClass方法总是返回原始类型。new Pair().getClass() ==  new Pair().getClass() 总是true
  • 不能创建参数化类型的数组,Pair [] table = new Pair [10]; // ERROR
    • 声明类型为Pair[]的变量仍是合法的
  • 不能实例化类型变量,不能使用像new T(...)
  • 泛型类的静态上下文中类型变量无效 private static T singleInstance; // ERROR
  • 不能抛出或捕获泛型类的实例
    • public class Problem  extends Exception { /* . . . */ } // ERROR—can't extend Throwable
    • catch子句中不能使用类型变量,catch (T e) // ERROR—can't catch type variable
    • 在异常规范中使用类型变量是允许的,public static  void doWork(T t) throws T {...}// OK

四、泛型类型的继承规则

  • Pair不是Pair的子类,而类型Pair是Pair<?extends Employee>的子类型
  • 带有超类型限定的通配符可以向泛型对象写入,带有子类型限定的通配符可以从泛型对象读取。
  • 超类定义: 或 ,但是不能声明,可以放入MyClass的子类或自己

你可能感兴趣的:(java,开发语言)