【问题标题】:How to return an interface from a method如何从方法返回接口
【发布时间】:2015-04-11 05:36:39
【问题描述】:

这是我的方法。我想从 Java 方法返回一组字符串。我想让调用代码决定是否要将这个集合实现为 VectorLinkedListArrayList 或其他实现 List 接口的东西。

public List<String> findAvailableLanguages() {
    Iterator<Map.Entry<String, String>> it = this.iterator();
    List<String> list = new ArrayList<String>();
    while (it.hasNext()) {
        Map.Entry<String, String> n = it.next();
        list.add(n.getKey());
    }

...

但是,为了构建集合,我必须在方法内部实例化一个具体的类对象。我现在返回什么将与任何实现 List 的类兼容?

这可能吗?

【问题讨论】:

标签: java methods interface return-type


【解决方案1】:

如果您允许在填充过程中传递List 而不是您自己发起,这对调用者更有效。它还将使代码易于单元测试,因为这就是称为依赖注入的模式。

public List<String> populateWithAvailableLanguages(List<String> list) {
    Iterator<Map.Entry<String, String>> it = this.iterator();
    // List<String> list = new ArrayList<String>();
    while (it.hasNext()) {
        Map.Entry<String, String> n = it.next();
        list.add(n.getKey());
    }
}

现在List的实现可以由调用者指定:

List<String> availableLanguages = new ArrayList<>();
Localizer.populateWithAvailableLanguages(availableLanguages);

【讨论】:

  • 我认为在这种情况下最好不要返回列表(即具有 void 返回类型),因为它会造成混乱。方法名称也应更改为 populateListWithAvailableLanguages 之类的名称,清楚地表明参数中传递的列表将被填充。
  • @coder:太好了!实际上,我除了复制原始代码和添加位之外没有做任何其他事情,但是您的建议对于保持代码的可维护性非常有用。
  • 我使用了这个解决方案并考虑了已回答的问题。谢谢。
  • 我将此回复标记为我使用的答案。我没有足够的声望来投票,而且我没有看到关闭问题的选项。
【解决方案2】:

简而言之,返回一个可以转换为任何其他实现 List 的对象类型的 ArrayList 对象类型是不可能的。可以遍历元素并将其添加到另一个对象类型,但不能强制转换集合类型本身。

我会解释原因。当你说,

List<String> list = new ArrayList<String>();

'list'的引用类型是List,对象类型是ArrayList。您现在拥有的“列表”对象使您可以访问 List 接口的所有方法,但不能访问 ArrayList 具有的其他方法,尽管列表对象可以看到它们(有点像缩小转换)。您可以将此列表对象转换回 ArrayList 对象,这将起作用,因为列表实例无论如何都可以看到 ArrayList 具有的方法,因此将其转换回将起作用(有点像扩大转换回原始宽度)。

但是,如果您要将它强制转换为实现 List 接口的其他类之一,如 LinkedList 或 Vector 或 Stack,会发生什么?列表实例不知道 LinkedList、Vector 或 Stack 中的其他方法是如何实现的(因为它们不在 ArrayList 中)。所以这有点像你不知道需要做什么的转换。所以它会抛出一个编译器错误。

扩展这个,你可以看到,如果你有:

List<String> list = new LinkedList<String>();

现在,将列表转换回 LinkedList 将起作用,但不能转换回 ArrayList。

【讨论】:

    【解决方案3】:

    您的方法签名应如下所示

    公共收藏(?super List) findAvailableLanguages(){}

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2017-03-04
      • 2021-02-05
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-09-28
      • 1970-01-01
      相关资源
      最近更新 更多