【问题标题】:How can I define in clojure a java class during runtime and instantiate it如何在运行时在 clojure 中定义一个 java 类并实例化它
【发布时间】:2015-11-03 17:10:14
【问题描述】:

我曾尝试使用clojure.core 中的gen-and-load-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)))))

在我做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!

【问题讨论】:

  • 您具体要解决什么问题?换句话说,您需要定义这个 Java 类的目的是什么?
  • 我正在构建原型,允许构建简洁的功能和缓存不经意的数据结构。为此,我需要构建等效的 C 严格模型数据结构作为数组而不使用引用等。
  • 为什么?在这种情况下,defrecorddeftype 有什么问题?
  • 我需要可变基元和数组字段。
  • deftype 为您提供。

标签: clojure gen-class


【解决方案1】:

除非您绝对需要 Java 类的所有灵活性,否则我建议您改用 deftype。正如here 解释的那样,deftype 让您能够以惯用的方式访问较低级别的构造,例如原始类型和可变性。

【讨论】:

    猜你喜欢
    • 2012-10-08
    • 1970-01-01
    • 2019-05-20
    • 1970-01-01
    • 1970-01-01
    • 2019-01-29
    • 2020-06-25
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多