Search code examples
clojureclojure-java-interop

How to call a static method on an incoming class-pointer in Clojure?


I wanted to get the bit size of bounded primitives in Clojure. These can be found with

(java.lang.Integer/SIZE)
=>32

or the equal, less sweet

(. java.lang.Integer SIZE)
=> 32

(I use java.lang.*-names just for clarity in these examples, they can be omitted)

Of course I wanted to parametrize the call, like

(def integer-class java.lang.Integer)

(. integer-class SIZE)
CompilerException java.lang.RuntimeException: Unable to resolve symbol: intger-class in this context, compiling:(/private/var/folders/yt/g82v06jn63qc5273rx4zjx440000gn/T/form-init4887476821027963248.clj:1:1) 

The number of bounded primitives are limited in Java, which makes this exercise a bit academic, but the questions would be:

How do I (dynamically) call a static method in a class given as a var?


Solution

  • As ponzao says, the Clojure vars and Java static methods has an answer with a macro jcall that solves the problem.

    (defmacro jcall [obj & args]
      (let [ref (if (and (symbol? obj) 
                      (instance? Class (eval obj)))
                  (eval obj)
                  obj) ]
        `(. ~ref ~@args)))
    
    (jcall java.lang.Integer SIZE) => 32!
    

    Thanks.