我在对象中有一个变量:
private final Map<Long, ? extends MovieInfoDTO> bElementsToAdd = new HashMap<>();
Run Code Online (Sandbox Code Playgroud)
使用Builder模式中的方法我想完成这个地图。
public Builder withElementsToAdd(@Nullable final Map<Long, ? extends MovieInfoDTO> elementsToAdd) {
this.bElementsToAdd.clear();
if(elementsToAdd != null) {
this.bElementsToAdd.putAll(elementsToAdd);
}
return this;
}
Run Code Online (Sandbox Code Playgroud)
但是,我收到一个错误。
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>>)
Run Code Online (Sandbox Code Playgroud)
如何更正这种补充地图的方法?
简短回答:您不能向具有该类型的地图添加值。根据经验,您可以读取? extends为“只读”,因此您的地图是“只读”MovieInfoDTO对象的地图。
更长的答案:? extends T有点奇怪;当您遇到问题时,类型检查器会将类型不同的不同句法出现表达式? extends T视为不同的、不兼容的“捕获”,这些“捕获”不会将类型检查视为彼此相等。所以既然bElementsToAdd有 type Map<Long, ? extends MovieInfoDTO>,那么就bElementsToAdd.put()取一个新“捕获”的值? extends MovieInfoDTO。但是没有办法获得同样的捕获!即使你这样做了bElementsToAdd.put(k, bElementsToAdd.get(k)),put和get使用不同的捕获,所以它们不是兼容的类型!
您显然不想要只读地图,因为您正在尝试更新它。所以,你有几个选择。一种是删除通配符——如果你不关心MovieInfoDTO你有什么子类型并且你可以在同一张地图中混合它们,那么这是有道理的。如果您确实在意,那么您可能打算为您的整体地图添加一个边界:
class MyClass<T extends MovieInfoDTO> {
// ...
private final Map<Long, T> bElementsToAdd = new HashMap<>();
//...
public Builder withElementsToAdd(@Nullable final Map<Long, T> elementsToAdd) {
// ...
}
Run Code Online (Sandbox Code Playgroud)
这会强制执行约束,即您添加的元素类型withElementsToAdd必须与地图中的元素类型相同,即使您不关心它是什么类型。
当您在 的 声明中放置上限通配符时bElementsToAdd,编译器不知道MovieInfoDTO您拥有哪种子类型。从理论上讲,您可以合法地将 a Map<Long, MovieInfoSubclassDTO>(MovieInfoSubclassDTO作为其理论子类MovieInfoDTO)分配给bElementsToAdd。
该方法putAll应该能够将另一个地图中的所有映射放入原始地图中。它的类型可以高达Map<Long, MovieInfoDTO>。该变量bElementsToAdd必须能够接受MovieInfoDTOs 作为键。
解决方案:删除 上的通配符上限bElementsToAdd。
private final Map<Long, MovieInfoDTO> bElementsToAdd = new HashMap<>();
Run Code Online (Sandbox Code Playgroud)
您不需要删除elementsToAdd( 的参数withElementsToAdd) 上的上限通配符,也不应该删除它。此处保留上限通配符允许调用代码传入 a Map<Long, MovieInfoSubclassDTO>,这是可以接受的,因为类型MovieInfoSubclassDTO( 的理论子类)MovieInfoDTO应该被允许作为 中的值bElementsToAdd。
| 归档时间: |
|
| 查看次数: |
5260 次 |
| 最近记录: |