In Clojure, how to use a java Class that is stored in a variable?
How should I fix the following code?
(def a java.lang.String)
(new a "1"); CompilerException java.lang.IllegalArgumentException: Unable to resolve classname: a
And why this one works fine?
(def a str)
(a "1")
Clojure solved this new language library problem by running on the JVM and having interoperability with Java classes. When you use Clojure, you can use Java classes and Java libraries. Clojure builds on the strength of the production-hardened and tested JVM and existing Java libraries.
Dynamic Class creation enables you to create a Java class on the fly at runtime, from source code created from a string. Dynamic class creation can be used in extremely low latency applications to improve performance.
MyClass with a method named mymethod, gen-class will generate an implementation that looks for a function named by (str prefix mymethod) (default prefix: "-") in a Clojure namespace specified by :impl-ns (defaults to the current namespace).
The most elegant solution is to write construct
that does the same as new
but is able to receive a class dynamically:
(defn construct [klass & args]
(clojure.lang.Reflector/invokeConstructor klass (into-array Object args)))
(def a HashSet)
(construct a '(1 2 3)); It works!!!
This solution overcomes the limitation of @mikera's answer (see comments).
Special Thanks to @Michał Marczyk that made me aware of invokeConstructor
answering another question of mine: Clojure: how to create a record inside a function?.
Another option is to store the call to the constructor as an anonymous function. In our case:
(def a #(String. %1))
(a "111"); "111"
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With