在编译完成之后尽快发现错误是值得的,理想情况是在编译时
在泛型被添加到 Java 之前,这是一个典型的集合声明
// Raw collection type - don't do this!
// My stamp collection. Contains only Stamp instances.
private final Collection stamps = ... ;
如果你今天使用这个声明,然后不小心把 coin 实例放入你的 stamp 集合中,错误的插入编译和运行没有错误(尽管编译器发出一个模糊的警告):
// Erroneous insertion of coin into stamp collection
stamps.add(new Coin( ... )); // Emits "unchecked call" warning
直到您尝试从 stamp 集合中检索 coin 实例时才会发生错误
// Raw iterator type - don't do this!
for (Iterator i = stamps.iterator(); i.hasNext(); )
Stamp stamp = (Stamp) i.next(); // Throws ClassCastException
stamp.cancel();
例外
类字面值(class literals)
List.class ,String[].class 和 int.class 都是合法的
List<String>.class 和 List<?>.class 不是合法的
instanceof 操作符
因为泛型类型信息在运行时被删除,所以在无限制通配符类型以外的参数化类型上使用 instanceof 运算符是非法的
以下是使用泛型类型的instanceof 运算符的首选方法:
// Legitimate use of raw type - instanceof operator
if (o instanceof Set) { // Raw type
Set<?> s = (Set<?>) o; // Wildcard type
...
}
请注意,一旦确定 o 对象是一个 Set ,则必须将其转换为通配符 Set<?> ,而不是原始类型 Set 。 这是一个强制转换,所以不会导致编译器警告。
为了快速参考,下表中总结了本条目(以及本章稍后介绍的一些)中介绍的术语:
术语 | 中文含义 | 举例 | 所在条目 |
Parameterized type | 参数化类型 | List<String> | 条目 26 |
Actual type parameter | 实际类型参数 | String | 条目 26 |
Generic type | 泛型类型 | List<E> | 条目 26 |
Formal type parameter | 形式类型参数 | E | 条目 26 |
Unbounded wildcard type | 无限制通配符类型 | List<?> | 条目 26 |
Raw type | 原始类型 | List | 条目 26 |
Bounded type parameter | 限制类型参数 | <E extends Number> | 条目 29 |
Recursive type bound | 递归类型限制 | <T extends Comparable<T>> | 条目 30 |
Bounded wildcard type | 限制通配符类型 | List<? extends Number> | 条目 31 |
Generic method | 泛型方法 | static <E> List<E> asList(E[] a) | 条目 30 |
Type token | 类型令牌 | String.class | 条目 33 |