如何从方法 return 接口

How to return an interface from a method

这是我的方法。我想 return 来自 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());
    }

...

但是,我必须在方法内部实例化一个具体的 class 对象才能构建集合。我现在要做什么 return 才能与任何实现 List 的 class 兼容?

这可能吗?

您的方法签名应如下所示

Public Collection(? super List) findAvailableLanguages(){}

如果您允许在填充过程中传递 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);

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

我会解释原因。当你说,

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

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

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

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

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

现在,将列表转换回 LinkedList 可以,但不能转换回 ArrayList。