当前位置: 首页 > 面试题库 >

类型参数与无界通配符

娄德运
2023-03-14
问题内容

摘自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的一致性比使用哪种样式更为重要。



 类似资料:
  • 问题内容: 最近,我读了这篇文章:http : //download.oracle.com/javase/tutorial/extra/generics/wildcards.html 我的问题是,而不是创建像这样的方法: 我可以创建一个这样的方法,它可以正常工作: 我应该使用哪种方式?通配符在这种情况下有用吗? 问题答案: 这取决于您 需要 做什么。如果要执行以下操作,则需要使用bounded t

  • 在了解Java泛型的过程中,我遇到了以下问题: 假设我有下面的方法来添加列表的元素,只限于包含数字的列表。 但是这段代码和这段代码有什么不同: 它们都按预期编译和执行。这两者之间有什么区别?除了语法之外?什么时候我更喜欢使用通配符而不是前者? 是的,使用通配符方法,我不能在列表中添加除null之外的新元素,否则它将无法编译。除此之外呢?

  • 问题内容: 我有一个接口将对象转换为字符串: 以及用于存储所有可用转换器的地图: 现在,我有了要转换的异构数据列表,如下所示: 但是此代码无法编译: 我应该如何更改代码? 问题答案: 您面临的问题称为通配符捕获。Java无法识别将从数据中接收的类型。尝试以两种方式中的任何一种重构代码 方法1:如下 更改您的界面 方法2: 通过类型推断来捕获通配符的Helper方法 创建如下的帮助方法, 如下调用此

  • 问题内容: 我正在刷新有关Java泛型的知识。因此,我转向了Oracle的优秀教程……并开始为我的同事编写一个演示文稿。我在本教程中遇到了有关通配符的部分,内容为: 考虑以下方法,printList: printList的目标是打印任何类型的列表,但未能实现该目标- 它仅打印Object实例的列表;它不能打印,,,等等,因为它们不是的亚型。要编写通用的printList方法,请使用: 我知道那是行

  • null 为什么我不能在MyList中添加对象。因为如果我们使用super,这意味着这个列表可以包含在Java类的继承制度中等于或高于number的对象。因此应该按照该语句在列表中添加新的Object()。 多谢了。

  • 问题内容: 我试图理解Java泛型,它们似乎很难理解。例如,这很好… …就是这个… … 还有这个 … …但是不能编译: 有人可以用简单的语言解释发生了什么吗? 问题答案: 对于泛型类型,主要要了解的是它们不是协变的。 因此,尽管您可以这样做: 以下内容将无法编译: 这是为了避免您绕过通用类型的情况: 因此,一一讲解您的示例 1个 您的通用方法采用a ,而您采用;(基本上是)。可以分配给类型,并且编