如何将 Java 17 记录转换为 Clojure 映射?

diz*_*iaq 7 clojure java-record java-17

有一个clojure.core/bean将 POJO 转换为 Map 的标准函数:

class MyPojo{
  public String getFirst(){ return "abc"; }
  public int getSecond(){ return 15; }
}

IFn bean = Clojure.var("clojure.core", "bean")

var result = bean.invoke(new MyPojo())

// result => {:first = abc, :second = 15}
Run Code Online (Sandbox Code Playgroud)

对于 Java 17 记录类,此函数不起作用,因为记录不遵循 POJO"get***"属性约定。

Clojure 是否以同样的方式支持 Java 17 记录实例?

ama*_*loy 9

Java 16 引入了Class.getRecordComponents. 因此,给定记录的实例,您可以查找记录的类,并从那里查找其记录组件。每个记录组件都有一个名称和一个 getter 方法,您可以使用它来查找该组件的值。您可以将这些部分组合在一起来构建bean.

(defn record->map [r]
  (into {} (for [^java.lang.reflect.RecordComponent c (seq (.getRecordComponents (class r)))]
             [(keyword (.getName c))
              (.invoke (.getAccessor c) r nil)])))
Run Code Online (Sandbox Code Playgroud)