Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

In Clojure, how to use a java Class dynamically?

Tags:

clojure

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")
like image 390
viebel Avatar asked Feb 06 '12 21:02

viebel


People also ask

Is clojure interoperable with Java?

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.

Can we create dynamic class in Java?

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.

What does Gen class do Clojure?

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).


1 Answers

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"
like image 128
viebel Avatar answered Oct 20 '22 17:10

viebel