在评估或编译 clojure.lang.IType 实现时,编译器会尝试反射性地访问其字段。如果字段被标记为可变(即私有),则会导致错误。
`
Clojure 1.9.0-master-SNAPSHOT
user=> (deftype T [^:unsynchronized-mutable t])
user.T
user=> (T. :t)
object[user.T 0x2654635 "user.T@2654635"]
user=> (eval (T. :t))
CompilerException java.lang.IllegalArgumentException: 在类 user.T 中找不到匹配的字段:t
Reflector.java: 271 clojure.lang.Reflector/getInstanceField
Compiler.java: 4724 clojure.lang.Compiler$ObjExpr/emitValue
Compiler.java: 4851 clojure.lang.Compiler$ObjExpr/emitConstants
Compiler.java: 4529 clojure.lang.Compiler$ObjExpr/compile
Compiler.java: 4049 clojure.lang.Compiler$FnExpr/parse
Compiler.java: 6866 clojure.lang.Compiler/analyzeSeq
Compiler.java: 6669 clojure.lang.Compiler/analyze
Compiler.java: 6924 clojure.lang.Compiler/eval
Compiler.java: 6890 clojure.lang.Compiler/eval
core.clj: 3105 clojure.core/eval
...
`
对于不实现 IType 的类,不存在此类问题。
`
user> (deftype* user/U user.U)
[^:unsynchronized-mutable u]
:implements [])
nil
user> (eval (user.U. :u))
object[user.U 0x34699051 "user.U@34699051"]
`
此问题通常发生在实现带有缓存的散列的 tagged literal 的 deftype 时。