Java 如何要求参数为可变映射?
我有一个函数,它接受参数的映射,但在使用它们之前添加:Java 如何要求参数为可变映射?,java,collections,guava,Java,Collections,Guava,我有一个函数,它接受参数的映射,但在使用它们之前添加: public String doRequest(String endpoint, Map<String, String> parameters) { parameters.put("limit", "50"); ... } 但是,这会在运行时抛出一个java.lang.UnsupportedOperationException 两个问题: 1) 我是否可以声明doRequest,例如HashMap和TreeMa
public String doRequest(String endpoint, Map<String, String> parameters) {
parameters.put("limit", "50");
...
}
但是,这会在运行时抛出一个java.lang.UnsupportedOperationException
两个问题:
1) 我是否可以声明doRequest
,例如HashMap
和TreeMap
就可以了,但是使用ImmutableMap
将是编译时错误
2) 从
doRequest
内部,我如何检测它是ImmutableMap
,这样我就可以运行params=Maps.newHashMap(params)
?嗯,ImmutableMap
是一个Map
的事实是一个糟糕的子类型,违反了LSP-这是你为它付费的。子类型无法履行其父类型的约定。。。这是ImmutableMap
从map继承的错误OOP(因为map
指定了一个put
),Java没有提供足够强大的构造来实施这些保证
至于一个解决方案——要么是你将要变异传入的
映射的文档,要么作为替代方案,不要变异传入的映射,而是自己返回一个新的不可变映射,事实上,ImmutableMap
是一个Map
是一个糟糕的子类型,并且违反了LSP——这是你为它付出的代价。子类型无法履行其父类型的约定。。。这是ImmutableMap
从map继承的错误OOP(因为map
指定了一个put
),Java没有提供足够强大的构造来实施这些保证
至于一个解决方案——要么是你将要变异传入的Map
的文档,要么作为替代方案,不要变异传入的Map
——而是自己返回一个新的ImmutableMap
1) 我是否可以以一种方式声明doRequest,例如HashMap和TreeMap就可以了,但是使用ImmutableMap将是一个编译时错误
不可以。由于ImmutableMap
实现了Map
,因此它不能是编译时错误。问题实际上在于Map.put
,它允许抛出。最好有一个Map
而不带put
和一个MutableMap
接口。。。但是在Java中,任何人都无法对它做任何事情,因为所有的软件都依赖它
2) 从doRequest内部,我如何检测它是一个不可变映射,以便运行params=Maps.newHashMap(params)
你最好总是这样做,因为还有集合。不可修改的映射
,实际上每个人都可以实现一个映射
拒绝放置
如果您关心性能,则需要进行instanceof
检查
1) 我是否可以以一种方式声明doRequest,例如HashMap和TreeMap就可以了,但是使用ImmutableMap将是一个编译时错误
不可以。由于ImmutableMap
实现了Map
,因此它不能是编译时错误。问题实际上在于Map.put
,它允许抛出。最好有一个Map
而不带put
和一个MutableMap
接口。。。但是在Java中,任何人都无法对它做任何事情,因为所有的软件都依赖它
2) 从doRequest内部,我如何检测它是一个不可变映射,以便运行params=Maps.newHashMap(params)
你最好总是这样做,因为还有集合。不可修改的映射
,实际上每个人都可以实现一个映射
拒绝放置
如果你关心性能,那么你需要一个instanceof
检查。至于检测类型-你可以使用instanceof
,是的-这是一个糟糕的oop,但是从Map
继承的ImmutableMap
首先也是如此。请告诉我如何违反这个规则?去掉那个咆哮,得到我的+1。@OlivierGrégoire确定,Map
公开了一个,这意味着您可以向Map
添加内容-这违反了-更好的设计是不要将方法放在Map
上,而是使用树映射和哈希映射
继承的可变映射
,或者在语言中有一个更强烈的常量概念。@OlivierGrégoire我并不是说不可变映射是个坏主意,事实上我的大部分工作和我自己的许多代码都使用不可变集合。然而-ImmutableMap实现Map
实际上是一个坏主意,因为它意味着它可以做它真正做不到的事情(比如put
),而这正是mine OP踩到的——我同意这不是ImmutableMap
的错(因为在那里实现Map是有意义的,因为它是人们在Java中所期望的)这更多的是Map
s的错误-但这并不能减少oop的糟糕程度。@BenjaminGruenbaum:Map
的契约明确允许在Map
实现上不支持变异操作。您当然可以争辩说,Map
不应该以这种方式指定,但它确实极大地简化了集合框架的类型层次结构,并且在实践中不是一个重大问题,只要您不假设给定的任何任意Map
都是可变的,而不将其作为方法的明确要求(听起来你还是同意这一点)。至于检测类型-你可以使用instanceof
,是的-这是一个糟糕的oop,但是从映射继承不可变映射也是如此。请告诉我如何违反?删除该咆哮以获得我的+1。@OlivierGré当然,映射
会暴露一个错误,这意味着你可以向映射添加内容e> -这违反了-更好的设计不是在地图上放置方法,而是
doRequest("/comments", ImmutableMap.of("filter", "true"));