2015-11-03 4 views
1

Я пытался использовать gen-and-load-class из clojure.core, а затем использовать пользовательский загрузчик классов для вызова defineClass с генерируемым байткодом, но когда я называюКак я могу определить в Clojure класса Java во время выполнения и создать его экземпляр

(foo.bar.MyClass.) 

I «получаю

CompilerExceptionjava.lang.NoClassDefFoundError: Could not initialize class foo.bar.MyClass 

UPDATE:

так что я использовал deftype как это было предложено @Elogent:

(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!

+1

Какая проблема конкретно вы пытаетесь решить? Другими словами, для чего вам нужен этот класс Java, который вы определяете? –

+0

Я строю прототип, позволяющий строить лаконичные функции и кэшировать забытые структуры данных. Для этого мне нужно построить эквивалент строгих структур данных модели C как массивы без использования ссылок и т. Д. – Lambder

+0

Почему? Что случилось с ['defrecord'] (http://clojuredocs.org/clojure.core/defrecord) или [' deftype'] (http://clojuredocs.org/clojure.core/deftype) в этом случае? –

ответ

1

Если вам не нужна вся гибкость класса Java, я бы посоветовал вместо этого использовать deftype. Как объяснено, here, deftype дает вам доступ к конструкциям нижнего уровня, таким как примитивные типы и изменчивость, идиоматическим способом.

 Смежные вопросы

  • Нет связанных вопросов^_^