键入参数vs无界通配符

dbf*_*dbf 10 java generics

从Effective Java第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);
Run Code Online (Sandbox Code Playgroud)

这两个声明中的哪一个更可取,为什么?在公共API中,第二个更好,因为它更简单.您传入一个列表 - 任何列表 - 并且该方法交换索引元素.没有类型参数需要担心.通常,如果类型参数在方法声明中仅出现一次,请将其替换为通配符.

我不明白为什么第二个选项对我的API客户来说更简单?我可以将相同的参数传递给第一和第二种方法.第二个需要辅助方法来进行通配符捕获.有人可以解释为什么推荐第二个?谢谢!

xwo*_*ker 11

Java Generics常见问题解答是回答这些问题的一个很好的来源,并且详细讨论了"通配符与通用"这一问题,其中一个更好:带有类型参数的通用方法或带有通配符的非通用方法?以及随后的案例研究.

Angelika Langer得出结论:

结论:在所有这些示例中,无论您更喜欢通用版还是通配符,都主要是品味和风格问题.通常在实现的简易性(通用版本通常更容易实现)和签名的复杂性之间进行权衡(通配符版本具有较少的类型参数或根本没有).

更简单的方法签名 - >更容易理解(即使两者都以相同的方式使用) - >良好的公共API(权衡:更复杂的实现)

但整个问题是一个轻量级的问题,根据我的经验,整个API的一致性比你使用的样式更重要.

  • 请改进您的答案,而不是仅仅将其标记为链接答案.至少在报价表格中复制你答案中链接的相关内容(在段落开头使用">"符号). (3认同)