Для создания экземпляра класс в clojure можно воспользоваться специальной формой new
Первый шаг создания объекта по имени класса - это найти полное имя класса, решается с помощью функции ns-resolve. Поиск выполняется в текущем пространстве имен(*ns*)
Если конструктор класса с параметрами, необходимо найти конструктор с подходящей сигнатурой(метод getConstructor класса java.lang.reflect.Constructor). И создать новый объект методом newInstance.
Окончательно функция будет выглядеть так:
(new String)или более краткой записью '.'
(String.)Но не всегда этих средств достаточно. Возникает необходимость создания объекта класса, зная только имя целевого класса(например хранящегося в виде строки "String"). В этом случае объект можно создать воспользовавшись методами java-классов java.lang.Class(для классов с конструктором без параметров) и java.lang.reflect.Constructor - для конструкторов с параметрами.
Первый шаг создания объекта по имени класса - это найти полное имя класса, решается с помощью функции ns-resolve. Поиск выполняется в текущем пространстве имен(*ns*)
(ns-resolve *ns* (symbol "String"))
java.lang.String
В случае успеха ns-resolve возвращает экземпляр класса java.lang.Class.Если конструктор класса с параметрами, необходимо найти конструктор с подходящей сигнатурой(метод getConstructor класса java.lang.reflect.Constructor). И создать новый объект методом newInstance.
Окончательно функция будет выглядеть так:
(defn new-instance [name & args] (let [class (ns-resolve *ns* (symbol name))] (if (= java.lang.Class (type class)) (if args (let [type-args (into-array java.lang.Class (map #(type %) args))] (.newInstance (.getConstructor class type-args) (into-array args))) (.newInstance class)))))Пример использования
user=> (new-instance "String") "" user=> (new-instance "String" "abc") "abc" user=> (type (new-instance "String" "123")) java.lang.String
Комментариев нет:
Отправить комментарий