Calling clojure from java

前端 未结 9 1546
梦毁少年i
梦毁少年i 2020-11-22 11:13

Most of the top google hits for \"calling clojure from java\" are outdated and recommend using clojure.lang.RT to compile the source code. Could you help with a

9条回答
  •  借酒劲吻你
    2020-11-22 11:25

    As of Clojure 1.6.0, there is a new preferred way to load and invoke Clojure functions. This method is now preferred to calling RT directly (and supersedes many of the other answers here). The javadoc is here - the main entry point is clojure.java.api.Clojure.

    To lookup and call a Clojure function:

    IFn plus = Clojure.var("clojure.core", "+");
    plus.invoke(1, 2);
    

    Functions in clojure.core are automatically loaded. Other namespaces can be loaded via require:

    IFn require = Clojure.var("clojure.core", "require");
    require.invoke(Clojure.read("clojure.set"));
    

    IFns can be passed to higher order functions, e.g. the example below passes plus to read:

    IFn map = Clojure.var("clojure.core", "map");
    IFn inc = Clojure.var("clojure.core", "inc");
    map.invoke(inc, Clojure.read("[1 2 3]"));
    

    Most IFns in Clojure refer to functions. A few, however, refer to non-function data values. To access these, use deref instead of fn:

    IFn printLength = Clojure.var("clojure.core", "*print-length*");
    IFn deref = Clojure.var("clojure.core", "deref");
    deref.invoke(printLength);
    

    Sometimes (if using some other part of the Clojure runtime), you may need to ensure that the Clojure runtime is properly initialized - calling a method on the Clojure class is sufficient for this purpose. If you do not need to call a method on Clojure, then simply causing the class to load is sufficient (in the past there has been a similar recommendation to load the RT class; this is now preferred):

    Class.forName("clojure.java.api.Clojure") 
    

提交回复
热议问题