提示三十一:使用限定通配符来增加 API 的灵活性。
- 对于任何两个不同类型的 Type1 和 Type2 , List<Type1> 既不是 List<Type2> 的子类型也不是其父类型。尽管List<String> 不是List<Object> 的子类型是违反直觉的,但它确实是有道理的。
- extends也称为上界通配符,就是指定上边界。即泛型中的类必须为当前类的子类或当前类。super也称为下界通配符,就是指定下边界。即泛型中的类必须为当前类或者其父类。
- 为了获得最大的灵活性,对代表生产者或消费者的输入参数使用通配符类型。有一个PECS原则,表示生产者使用extend,表示消费者使用super。输出尽量不要使用通配符。
- 如果类型参数在方法声明中只出现一次,请将其替换为通配符。
关于最后一点书中举了一个例子
public static void swap(List<?> list, int i, int j) {
list.set(i, list.set(j, list.get(i)));
}
试图编译它会产生报错Error:(81, 41) java: 不兼容的类型: java.lang.Object无法转换为capture#1
,需要这样才行:
public static void swap(List<?> list, int i, int j) {
swapHelper(list, i, j);
}// Private helper method for wildcard capture
private static <E> void swapHelper(List<E> list, int i, int j) {
list.set(i, list.set(j, list.get(i)));
}
作者认为这样更加优雅,允许导出基于通配符的漂亮声明,同时利用内部更复杂的泛型方法来实现功能。 swap 方法的客户端就不需要面对更复杂的 swapHelper 声明,但他们从中受益,辅助方法具有作者认为对公共方法来说过于复杂的签名。
这一章的内容是没有多难,但我觉得作者的要求是对于那些需要提供给外部的API,对于我们日常开发来说,其实不需要这么讲究普适性,我一般都是直接具体的类型,只有需要复用的时候才会想到去用这些通配符。但是按照作者的高标准来要求自己,确实有助于写出更严谨优美的代码。
网友评论