我在对象中有一个变量:
private final Map<Long, ? extends MovieInfoDTO> bElementsToAdd = new HashMap<>();
使用Builder模式中的方法我想完成这个 map 。
public Builder withElementsToAdd(@Nullable final Map<Long, ? extends MovieInfoDTO> elementsToAdd) {
this.bElementsToAdd.clear();
if(elementsToAdd != null) {
this.bElementsToAdd.putAll(elementsToAdd);
}
return this;
}
但是,我收到一个错误。
putAll
(java.util.Map<? extends java.lang.Long,? extends capture<? extends com.jonki.popcorn.common.dto.movie.MovieInfoDTO>>)
in Map cannot be applied
to
(java.util.Map<java.lang.Long,capture<? extends com.jonki.popcorn.common.dto.movie.MovieInfoDTO>>)
如何更正这种补充 map 的方法?
最佳答案
简短回答:您不能向具有该类型的 map 添加值。根据经验,您可以阅读 ? extends
为“只读”,因此您的 map 是“只读” map MovieInfoDTO
对象。
更长的答案:? extends T
有点奇怪;当您遇到问题时,类型检查器会考虑类型为 ? extends T
的不同句法出现表达式。是不同的,不兼容的“捕获”,它们的类型检查不相等。所以自从 bElementsToAdd
有类型 Map<Long, ? extends MovieInfoDTO>
,然后 bElementsToAdd.put()
取一个新的“捕获”值 ? extends MovieInfoDTO
.但是没有办法获得同样的捕获!即使你做了 bElementsToAdd.put(k, bElementsToAdd.get(k))
, put
和 get
使用不同的捕获,因此它们不是兼容的类型!
您显然不想要只读 map ,因为您正在尝试更新它。所以,你有几个选择。一种是删除通配符——如果您不关心 MovieInfoDTO
的子类型,这是有道理的。你已经有了并且你可以将它们混合在同一张 map 中。如果您确实在意,那么您可能打算为您的整体 map 添加一个边界:
class MyClass<T extends MovieInfoDTO> {
// ...
private final Map<Long, T> bElementsToAdd = new HashMap<>();
//...
public Builder withElementsToAdd(@Nullable final Map<Long, T> elementsToAdd) {
// ...
}
这会强制您在
withElementsToAdd
中添加的元素类型的约束。必须与 map 中的类型具有相同的类型,即使您不关心它是什么类型。
关于java - 不兼容的类型 : capture of ? extends ... 不能转换为捕获?延伸,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50380642/