Inconvertible types in Generics
Possible Duplicate:
Is `List` a subclass of `List`? Why aren’t Java’s generics implicitly polymorphic?
我需要帮助理解发生了什么。
我有一个接口
1 2 3 4 5 6
| public interface Foo {
Map <String, ParameterValue > getParameters ();
}
public interface ParameterValue { } |
以及foo的实现。
1 2 3 4 5 6 7 8 9 10
| 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 );
}
} |
我得到以下错误
1 2 3 4 5 6 7
| [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 is not applicable for the arguments (String, ParameterValueImpl)。
foo.getParameters().put("test", new ParameterValueImpl);
- stackoverflow.com/questions/2745265/&hellip;
想想看——如果getParameters()的返回值实际上是一个Map,那么您就可以向源自ParameterValue而不是ParameterValueImpl的映射中添加一个值。这样做会破坏类型安全。
您有两个选项可以更正此问题:
在getParameters()中,将地图复制到正确类型的新地图中。
使用Map作为FooImpl.parameters的类型。
- 我不能做第二部分,因为fooimpl是一个JPA实体,如果我使用这个接口,它将无法识别它。我不太明白这一点。
- 最后,您可能不得不使Foo成为一个通用接口,类型参数用作映射的第二个类型参数。
- 我理解复制部分,我改为理解。似乎暂时有效。
- 但是要小心,因为您要返回一个副本,所以向这个方法返回的映射中添加项目对FooImpl实例中包含的映射没有影响。考虑返回只读副本,以便任何修改映射的尝试都将导致错误。
您可以将接口方法更改为:
1
| Map <String, ? extends ParameterValue > getParameters (); |
现在,您可以返回String和任何实现ParameterValue的类型的映射。
那么在实现这个方法时就不需要进行类型转换了。
1 2 3
| public Map <String, ? extends ParameterValue > getParameters () {
return parameters ;
} |
或者,由于您可以在ParameterType引用中存储ParameterValueImpl类型实例,因此您也可以将FooImpl类中的Map更改为:
1
| Map <String, ParameterValue > parameters = new HashMap <String, ParameterValue >(); |
那你原来的方法就行了。
- 如果我使用? extends ParameterValue,那么下面的代码就不需要cx1〔3〕,它会给我错误消息The method put(String, capture#8-of ? extends ParameterValue) in the type Map is not applicable for the arguments (String, ParameterValueImpl)。
- 如果地图是? extends Type的类型,就不能修改它。因为您不知道可以实际插入哪种类型。如果你想修改你的地图。那你应该走第二条路。