我有一个接受Map
参数的函数,但在使用之前会添加它们:
public String doRequest(String endpoint, Map<String, String> parameters) {
parameters.put("limit", "50");
...
}
使用Guava&#39; ImmutableMap.of()
创建此地图很方便:
doRequest("/comments", ImmutableMap.of("filter", "true"));
但是,这会在运行时抛出java.lang.UnsupportedOperationException
。
两个问题:
1)我是否可以以doRequest
和HashMap
合适的方式声明TreeMap
,但使用ImmutableMap
会是编译时错误?
2)从doRequest
内部,我如何检测到它是ImmutableMap
,这样我才能运行params = Maps.newHashMap(params)
?
答案 0 :(得分:4)
嗯,ImmutableMap
是Map
的事实是错误的子类型和违反LSP的行为 - 这是你付出的代价。一个子类型无法履行其父类型的契约...这是ImmutableMap
继承自地图是错误的OOP(因为Map
指定了put
)而Java没有提供足够强大的构造执行这些保证。
至于解决方案 - 文档,你要改变传入的Map
,或作为替代方案,不要改变传入的Map
- 而是自己返回一个新的ImmutableMap
。
答案 1 :(得分:1)
1)我能否以一种方式声明doRequest,例如HashMap和TreeMap会没问题但使用ImmutableMap会是编译时错误?
没有。当ImmutableMap
实现Map
时,它不能是编译时错误。问题实际上是Map.put
,它允许抛出。最好不要Map
没有put
和MutableMap
接口...但是没有任何人可以在Java中做到这一点,因为周围的所有软件都依赖于它。 / p>
2)从doRequest内部,我如何检测到它是一个ImmutableMap,所以我可以运行params = Maps.newHashMap(params)?
你最好这样做,因为还有Collections.unmodifiableMap
,实际上每个人都可以实现Map
拒绝put
。
如果您关注效果,则需要进行instanceof
检查。