这是我的方法。我想从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());
}
...
但是,我必须在方法中实例化一个具体的类对象才能构建集合。我现在返回的是什么,它将与任何实现List
的类兼容?
这可能吗?
答案 0 :(得分:4)
如果您允许在填充过程中传递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);
的实现:
{{1}}
答案 1 :(得分:1)
简而言之,返回一个可以强制转换为实现List的任何其他对象类型的ArrayList对象类型是不可能的。可以遍历元素并将其添加到另一个对象类型,但不能转换集合类型本身。
我将解释原因。当你说,
List<String> list = new ArrayList<String>();
&#39;列表&#39;的引用类型是List,对象类型是ArrayList。 &#39;列表&#39;您现在拥有的对象使您可以访问List接口的所有方法,但不能访问ArrayList具有的其他方法,尽管列表对象可以看到它们(有点像缩小转换)。您可以将此列表对象强制转换回ArrayList对象,这样可以正常工作,因为列表实例无论如何都可以看到ArrayList具有的方法,因此将其转换回来会有效(有点像扩展转换回原始宽度)。
但是如果要将它转换为实现List接口的其他类之一,如LinkedList或Vector或Stack,会发生什么?列表实例不知道LinkedList,Vector或Stack中存在的其他方法是如何实现的(因为它们不在ArrayList中)。所以它有点像转换,你不知道需要做什么。所以它会抛弃编译器错误。
扩展这一点,你可以看到,如果你有:
List<String> list = new LinkedList<String>();
现在,将列表转换回LinkedList将起作用但不会返回到ArrayList。
答案 2 :(得分:-1)
您的方法签名应如下所示
Public Collection(?super List)findAvailableLanguages(){}