如何从方法 return 接口
How to return an interface from a method
这是我的方法。我想 return 来自 Java 方法的字符串集合。我想让调用代码决定是否要将此集合实现为 Vector
或 LinkedList
或 ArrayList
或实现 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。
这是我的方法。我想 return 来自 Java 方法的字符串集合。我想让调用代码决定是否要将此集合实现为 Vector
或 LinkedList
或 ArrayList
或实现 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。