我如何在运行时在 clojure 中定义 java class 并实例化它
How can I define in clojure a java class during runtime and instantiate it
我尝试使用 clojure.core
中的 gen-and-load-class
,然后使用自定义 class 加载程序来调用 defineClass
生成的字节码,但是当我调用
(foo.bar.MyClass.)
我得到
CompilerExceptionjava.lang.NoClassDefFoundError: Could not initialize class foo.bar.MyClass
更新:
所以我按照@Elogent 的建议使用了 deftype :
(defprotocol Struct
(getX [this path] "Get value")
(setX [this ^long value path] "Get value"))
(deftype Foo
[
^{:tag long :unsynchronized-mutable true} a
^{:tag long :unsynchronized-mutable true} b
^{:tag long :unsynchronized-mutable true} c]
Struct
(getX
[this [head & tail]]
(let [field (condp = head
'a a
'b b
'c c)]
(if (empty? tail)
field
(getX field tail))))
(setX
[this value [head & tail]]
(if (empty? tail)
(condp = head
(set! a (long value))
(set! b (long value))
(set! c (long value)))
(condp = head
(setX a value tail)
(setX b value tail)
(setX c value tail)))))
在 AOT 之后当我做 javap Foo.class
我得到:
public final class struct.core.Foo implements struct.core.Struct,clojure.lang.IType {
public static final clojure.lang.Var const__0;
public static final java.lang.Object const__1;
public static final clojure.lang.Var const__2;
public static final java.lang.Object const__3;
public static final clojure.lang.Var const__4;
public static final clojure.lang.AFn const__5;
public static final clojure.lang.AFn const__6;
public static final clojure.lang.AFn const__7;
public static final clojure.lang.Var const__8;
public static final clojure.lang.Var const__9;
public static final clojure.lang.Var const__10;
public static final clojure.lang.Var const__11;
public static final clojure.lang.Var const__12;
long a;
long b;
long c;
public static {};
public struct.core.Foo(long, long, long);
public static clojure.lang.IPersistentVector getBasis();
public java.lang.Object setX(java.lang.Object, java.lang.Object);
public java.lang.Object getX(java.lang.Object);
}
这正是我需要的。谢谢@Elogent!
我尝试使用 clojure.core
中的 gen-and-load-class
,然后使用自定义 class 加载程序来调用 defineClass
生成的字节码,但是当我调用
(foo.bar.MyClass.)
我得到
CompilerExceptionjava.lang.NoClassDefFoundError: Could not initialize class foo.bar.MyClass
更新:
所以我按照@Elogent 的建议使用了 deftype :
(defprotocol Struct
(getX [this path] "Get value")
(setX [this ^long value path] "Get value"))
(deftype Foo
[
^{:tag long :unsynchronized-mutable true} a
^{:tag long :unsynchronized-mutable true} b
^{:tag long :unsynchronized-mutable true} c]
Struct
(getX
[this [head & tail]]
(let [field (condp = head
'a a
'b b
'c c)]
(if (empty? tail)
field
(getX field tail))))
(setX
[this value [head & tail]]
(if (empty? tail)
(condp = head
(set! a (long value))
(set! b (long value))
(set! c (long value)))
(condp = head
(setX a value tail)
(setX b value tail)
(setX c value tail)))))
在 AOT 之后当我做 javap Foo.class
我得到:
public final class struct.core.Foo implements struct.core.Struct,clojure.lang.IType {
public static final clojure.lang.Var const__0;
public static final java.lang.Object const__1;
public static final clojure.lang.Var const__2;
public static final java.lang.Object const__3;
public static final clojure.lang.Var const__4;
public static final clojure.lang.AFn const__5;
public static final clojure.lang.AFn const__6;
public static final clojure.lang.AFn const__7;
public static final clojure.lang.Var const__8;
public static final clojure.lang.Var const__9;
public static final clojure.lang.Var const__10;
public static final clojure.lang.Var const__11;
public static final clojure.lang.Var const__12;
long a;
long b;
long c;
public static {};
public struct.core.Foo(long, long, long);
public static clojure.lang.IPersistentVector getBasis();
public java.lang.Object setX(java.lang.Object, java.lang.Object);
public java.lang.Object getX(java.lang.Object);
}
这正是我需要的。谢谢@Elogent!