我想在我的一个服务中有一个应该返回通用列表的方法。 然后我想从其他服务向该列表添加项目。
class Fruit;
class Apple extends Fruit;
class FruitService() {
private ArrayList<? extends Fruit> getList() {
return new ArrayList<Apple>();
}
}
class SomeService() {
init() {
fruitService.getList().add(new Apple());
}
}
这会出现以下错误:
The method add(capture#3-of ? extends Fruit) in the type ArrayList<capture#3-of ? extends Fruit> is not applicable for the arguments (Apple)
为什么呢?我怎样才能将Apple添加到该通用列表中?
我的目标是让getList()方法不返回特定的实现。
答案 0 :(得分:4)
你不能。
ArrayList<? extends Fruit>
实际上可能是
ArrayList<Apple>
虽然Banana
,但您无法插入Banana extends Fruit
。并且您无法插入Fruit
,因为它必须至少包含Apple
的内容。由于Java不再能够看到所需的类型,但必须保证它能够正常工作,它甚至不允许您插入Apple
,尽管实际列表允许这样做。
- &GT;除了List<? extends Whatever>
之外,您无法将任何插入null
,因为您不知道确切的类型。 ? extends Whatever
会生成Whatever
的只读列表。
如果你想返回常规&amp;有用的List
不会返回带有通配符类型的文件。
相反,您可以在FruitService
中使用泛型,例如
class FruitService<T extends Fruit> {
private ArrayList<T> getList() {
return new ArrayList<T>();
}
public void useList(T fruit) {
getList().add(fruit);
}
}
class User {
void foo() {
FruitService<Apple> appleService = new FruitService<Apple>();
appleService.useList(new Apple());
FruitService<Banana> bananaService = new FruitService<Banana>();
bananaService.useList(new Banana());
}
}
答案 1 :(得分:2)
您可以让getList()
方法返回List
(或ArrayList
} Fruit
代替吗?这样,您就可以将Fruit
的任何子类型插入List
。
private List<Fruit> getList() {
return new ArrayList<Fruit>();
}
答案 2 :(得分:2)
您可以将方法设为通用 -
public <T extends Fruit> List<T> getList() {
//....
类型变量T
可以捕获实际的类型参数,因此编译器可以采用类型安全性。
此外,您可以return new ArrayList<T>();
代替return new ArrayList<Apple>();
。