使用泛型返回接口实现中的错误

时间:2011-11-22 11:23:57

标签: java generics interface

我有一个定义这样一个方法的接口:

public List<IA> myMethod();

使用IA其他界面。

在我的方法实现中,我声明:

public List<A> myMethod() { /* Do something */ }

A一个实现IA的类。

然而,Java(或eclipse)不喜欢它并强迫我在List<IA>的实现中使用myMethod。当A实现IA时,我不明白为什么这会导致错误。

以下是问题:

  • 为什么会出现此错误?
  • 哪种方法可以避免它(知道我对代码没有太多自由)?

2 个答案:

答案 0 :(得分:5)

您遇到此错误,因为从类型安全的角度来看它是不安全的。考虑:

// Interface declaration
List<Fruit> myMethod();

// Implemented by...
public List<Banana> myMethod() {
    return new ArrayList<Banana>();
}

// Called as:
List<Fruit> fruit = foo.myMethod();
fruit.add(new Apple());

您真的希望能够Apple添加ArrayList<Banana>吗?

您可以通过将声明更改为

来解决此问题
List<? extends IA> myMethod();

这将阻止调用添加到列表(或设置值)。

如果您无法更改界面,您将 从您的方法中返回List<IA>,我担心。

有关更多信息,请参阅Java Generics FAQ

答案 1 :(得分:0)

由于interface中定义的合同规定myMethod必须返回类型为IA的列表。

作为一个拇指规则:当需要派生类对象时,可以在任何地方使用基类引用。但反之亦然。这就是错误。

要避免这些错误:请始终按照接口(合约)进行操作。