类型参数与无界通配符
问题内容:
摘自Effective Java Chapter 5(泛型):
// Two possible declarations for the swap method public static <E> void swap(List<E> list, int i, int j); public static void swap(List<?> list, int i, int j);
这两个声明中的哪一个是可取的,为什么?在公共API中,第二个更好,因为它更简单。您传入一个列表(任何列表),该方法交换索引元素。没有类型参数值得担心。通常,如果类型参数在方法声明中仅出现一次,则将其替换为通配符。
我不明白,为什么第二个选项对我的API客户端来说更简单?我可以将相同的参数传递给第一个和第二个方法。第二种方法也需要使用辅助方法进行通配符捕获。有人可以解释为什么建议第二吗?谢谢!
问题答案:
Java泛型FAQ是回答此类问题的好资源,并详细讨论了“通配符与泛型”一词,其中哪个更好:带类型参数的泛型方法或带通配符的非泛型方法?以及后续的案例研究。
Angelika Langer得出结论:
结论:在所有这些示例中,无论您偏爱通用版本还是通配版本,都主要取决于口味和风格。通常,在易于实现(通用版本通常更易于实现)与签名复杂度(通配符版本具有较少的类型参数或根本没有类型参数)之间进行权衡。
更简单的方法签名->更易于理解(即使两者都以相同的方式使用)->在公共API中很好(权衡:更复杂的实现)
但是,整个过程是一个轻量级的问题,根据我的经验,整个API的一致性比使用哪种样式更为重要。