Я не знаком с org.reflections, но если вы просто хотите получить список загруженных классов, вы можете получить его с помощью приведенного ниже кода:
(let [classloader (.getClassLoader clojure.main)
classes-field (.getDeclaredField java.lang.ClassLoader "classes")]
(.setAccessible classes-field true)
(let [class-list (.get classes-field classloader)
class-vec (reduce conj [] class-list)] ; copy everything into a new vector rather than working directly with the classloader's private field
class-vec))
Звучит так, как будто вы знакомы с Java, так что, я думаю, вы видите, что вышеизложенное - это просто переведенная Java. Это даст вам только те классы, которые были загружены с тем же загрузчиком классов, что и для класса clojure.main
, но если вы не выполнили никаких настроек со своими загрузчиками классов, этого должно быть достаточно.
Когда у вас есть этот список, вы можете искать / фильтровать его по своему усмотрению. Конечно, класс, который вы ищете, должен быть загружен первым. Если это не так, вам придется искать путь к классам.
=== ОБНОВЛЕНИЕ, чтобы ответить на ваш комментарий ===
Хорошо, я вижу, вы спрашиваете, как создать класс. Первое, что нужно сказать, это то, что вам обычно не нужно создавать именованные классы, когда вы пишете Clojure, если только вы не хотите специально использовать некоторый существующий код Java, который требует от вас этого. Если вы пишете чистый Clojure, вы просто пишете свои функции и работаете с ними напрямую.
Однако вы, конечно, можете это сделать. Первая часть документа для gen-class
гласит:
=> (doc gen-class)
clojure.core / генераторной класс
([& опции])
Macro
При компиляции генерирует скомпилированный байт-код для класса с
данный пакет уточнен: имя (которое, как и все имена в этих
параметров, может быть строкой или символом) и записывает файл .class
в каталог путь компиляции . Когда не компилируется, делает
ничего такого.
Итак, вам нужно скомпилировать ваше пространство имен. Обычно я этого не делаю, поэтому я не знаю, есть ли способ сделать это, не создавая файлы .class и просто создавая классы непосредственно в памяти, но нижеприведенное делает то, что вы хотите, если я вас правильно понял :
(ns wip.test)
; looks for wip/himplement.clj on the classpath, and compiles it into .class files
; requires that ../bin is in the classpath
(binding [*compile-path* "../bin"]
(compile 'wip.himplement))
; loads the wip.himplement class from the .class files
(Class/forName "wip.himplement")
; create a list of all loaded classes (could presumably also be done with org.reflections)
(def classes-list (let [classloader (.getClassLoader clojure.main)
classes-field (.getDeclaredField java.lang.ClassLoader "classes")]
(.setAccessible classes-field true)
(java.util.ArrayList. (.get classes-field classloader))))
; Outputs all loaded classes which implement HInterface. Output is:
; (wip.hello.HInterface wip.himplement)
(println (filter #(isa? % wip.hello.HInterface) classes-list))