如何通过gen-class在Clojure中生成可序列化的java类?

Posted

技术标签:

【中文标题】如何通过gen-class在Clojure中生成可序列化的java类?【英文标题】:How to generate a serializable java class in Clojure by gen-class? 【发布时间】:2013-02-10 07:32:01 【问题描述】:

我们需要通过Java序列化机制将Clojure生成的一堆Java对象序列化成一个文件。

(gen-class
 :name lancelot.Instance
 :extends cc.mallet.types.Instance)

(gen-class
 :name lancelot.FilterPipe
 :extends cc.mallet.pipe.Pipe
 :prefix "-filter-"
 :methods [[pipe [cc.mallet.types.Instance] lancelot.Instance]])

(defn -filter-pipe [this ^cc.mallet.types.Instance inst]
  (.setData inst (clojure.string/join " "
    (filter normal-word? (clojure.string/split (.getData inst) #"\s+"))))
  inst)

(gen-class
 :name lancelot.SegmentorPipe
 :extends cc.mallet.pipe.Pipe
 :prefix "-segmentor-"
 :methods [[pipe [cc.mallet.types.Instance] lancelot.Instance]])

(defn -segmentor-pipe [this ^cc.mallet.types.Instance inst]
  (.setData inst (seg/seg (.getData inst)))
  inst)

如上,lancelot.FilterPipe 和 lancelot.SegmentorPipe 的实例需要序列化。我们发现写对象流是可以的,但是重新编译代码后读取对象流就不行了。

线程“Thread-8”java.io.InvalidClassException 中的异常: lancelot.SegmentorPipe;本地类不兼容:流 classdesc serialVersionUID = 2583852145887230781,本地类serialVersionUID = -2255006751011717591 在 java.io.ObjectStreamClass.initNonProxy(ObjectStreamClass.java:579) 在 java.io.ObjectInputStream.readNonProxyDesc(ObjectInputStream.java:1601) 在 java.io.ObjectInputStream.readClassDesc(ObjectInputStream.java:1514) 在 java.io.ObjectInputStream.readOrdinaryObject(ObjectInputStream.java:1750) 在 java.io.ObjectInputStream.readObject0(ObjectInputStream.java:1347) 在 java.io.ObjectInputStream.readObject(ObjectInputStream.java:369)

由于serialVersionUID是静态的和final的,但是gen-class似乎只能生成实例级的final字段。所以问题是我无法为生成的类设置特定的serialVersionUID。

对这个问题有什么建议吗?提前致谢。

【问题讨论】:

谢谢。由于serialVersionUID 是静态的和最终的,但似乎gen-class 只能生成实例级别的最终字段。这就是原因! 见***.com/a/1584112/117220 【参考方案1】:

请尝试添加Serializable

(gen-class :name lancelot.Instance :implements [java.io.Serializable] :extends cc.mallet.types.Instance)

【讨论】:

以上是关于如何通过gen-class在Clojure中生成可序列化的java类?的主要内容,如果未能解决你的问题,请参考以下文章

具有需要枚举参数的注释的 clojure gen-class

将 Clojure 命名空间拆分为多个文件

如何在 Clojure 中调用公共类的非公共方法?

如何在 Clojure 中生成记忆递归函数?

Clojure:使用来自 REPL 的库函数

如何在 Python 中生成可重现(带有种子)的随机 UUID