3

可能重复:
`List<Dog>` 是 `List<Animal>` 的子类吗?为什么 Java 的泛型不是隐式多态的?

我需要帮助了解发生了什么。

我有一个界面

public interface Foo {

  Map<String, ParameterValue> getParameters();
}

public interface ParameterValue { }

以及 Foo 的一个实现。

class FooImpl implements Foo {
   Map<String, ParameterValueImpl> parameters = new HashMap<String, ParameterValueImpl>();
   //ParameterValueImpl an implementation of ParameterValue

@Override
    public Map<String, ParameterValue> getParameters() {
        return ((Map<String,ParameterValue>) parameters);
    }   

}

我收到以下错误

[ERROR] Failed to execute goal
failure [ERROR]
src/main/java/domainJPA/model/FooImpl.java:[92,45]
inconvertible types [ERROR] found   :
java.util.Map<java.lang.String,domainJPA.model.ParameterValueImpl>
[ERROR] required:
java.util.Map<java.lang.String,domain.model.ParameterValue>

我必须在 Foo 的接口中使用 ParameterValue,而在 FooImpl 中我必须只实现 ParameterValue (ParameterValueImpl),因为它是 @Entity 并且 jpa 需要它。

我怎样才能使这段代码编译?

编辑

如果我将代码更改? extends ParameterValue为答案之一中的建议,那么我将无法使用 Foo 接口。

以下代码导致编译错误:The method put(String, capture#8-of ? extends ParameterValue) in the type Map<String,capture#8-of ? extends ParameterValue> is not applicable for the arguments (String, ParameterValueImpl)

foo.getParameters().put("test", new ParameterValueImpl);

4

2 回答 2

6

想一想——如果 from 的返回值getParameters()实际上是 a Map<String, ParameterValueImpl>,那么您可以将一个值添加到从 派生的映射中ParameterValue,但不是ParameterValueImpl。这样做会破坏类型安全。

您有两个选项可以纠正此问题:

  1. getParameters()中,将地图复制到正确类型的新地图中。
  2. 用作Map<String, ParameterValue>的类型FooImpl.parameters
于 2012-11-09T15:51:31.307 回答
5

您可以将界面方法更改为: -

Map<String, ? extends ParameterValue> getParameters();

现在,您可以返回 MapString和实现您的任何类型ParameterValue

那么你在这个方法的实现中不需要类型转换。

public Map<String, ? extends ParameterValue> getParameters() {
    return parameters;
}   

或者,由于您可以将ParameterValueImpl类型实例存储在ParameterType引用中,因此,您还可以将类中的 更改MapFooImpl:-

Map<String, ParameterValue> parameters = new HashMap<String, ParameterValue>();

那么您的原始方法将起作用。

于 2012-11-09T15:52:36.877 回答