Cuando se define una de esta manera, se obtiene un var contiene un java.lang.Class
(def a java.lang.String)
(type a)
=> java.lang.Class
A continuación, tiene 2 opciones:
A: Construir la nueva instancia dinámicamente al encontrar el constructor de Java utilizando la API de reflexión. Tenga en cuenta que como señala Yehonathan es necesario utilizar la clase exacta se define en la firma constructora (una subclase no funcionará, ya que no va a encontrar la firma correcta):
(defn construct [klass & args]
(.newInstance
(.getConstructor klass (into-array java.lang.Class (map type args)))
(object-array args)))
(construct a "Foobar!")
=> "Foobar!"
B: Construir el uso de Clojure interoperabilidad de Java, que requerirá una eval:
(defn new-class [klass & args]
(eval `(new ~klass [email protected])))
(new-class a "Hello!")
=> "Hello!"
Tenga en cuenta que el método a es considerablemente más rápido (alrededor de 60 veces más rápido en mi máquina), creo que principalmente porque evita la sobrecarga de invocar el compilador Clojure para cada sentencia eval.
Pensé que esto ha aparecido antes y de hecho lo ha hecho: ver [Clojure: crear una instancia nueva a partir del nombre de la clase String] (http: // stackoverflow.com/q/3748559/232707) con una gran respuesta de Chouser que menciona tanto 'clojure.lang.Reflector/invokeConstructor' como otro enfoque, una especie de término medio entre" estático + rápido "y" dinámico + lento "(podría llámalo "muy dinámico + lento una vez, estático + rápido después"), que bien puede interesarte. –