在补丁之前
`
user=> (definterface I (f []))
user.I
user=> (def p (proxy [Object I] [] (f [] 1)))
'user/p
user=> (definterface I (f []))
user.I
user=> (def p (proxy [Object I] [] (f [] 1)))
'user/p
user=> (.f ^I p)
ClassCastException user.proxy$java.lang.Object$I$383c225e 无法转换为 user.I user$eval7491.invokeStatic (:1)
`
在补丁之后
`
user=> (definterface I (f []))
user.I
user=> (def p (proxy [Object I] [] (f [] 1)))
'user/p
user=> (definterface I (f []))
user.I
user=> (def p (proxy [Object I] [] (f [] 1)))
'user/p
user=> (.f ^I p)
1
`
原因: proxy
使用一组类名缓存生成的类(见 https://github.com/clojure/clojure/blob/master/src/clj/clojure/core_proxy.clj#L280-L286),在接口重定义的情况下这不安全
建议:更改用于确定代理类缓存匹配的哈希函数,使其考虑每个接口/超类的身份,而不仅仅是它们的名字
补丁: 0001-CLJ-2379-idempotent-proxy-name-just-on-identical-ins-v2.patch