在Clojure中调用非静态Java方法

时间:2020-06-10 22:35:58

标签: java clojure interop

在Clojure中调用静态Java方法很顺利;没问题。但是,当我调用非静态方法时,尽管我已经尝试对点(。)表示法进行了多种变体,但仍引发了错误,如Clojure Interop documentation所述。

Java类:

public class CljHelper {

  public void test(String text) {
    System.out.println(text);
  }

}

Clojure代码:

(ns com.acme.clojure.Play
  (:import [com.acme.helpers CljHelper]))

(. CljHelper test "This is a test")  

错误:

java.lang.IllegalArgumentException: No matching method: test

这是另一种尝试,它使Java方法得以执行,但紧随其后引发错误:

(defn add-Id
  [x]
  (let [c (CljHelper.)]
    ((.test c x))))        ;;; java.lang.NullPointerException: null in this line

(add-Id "id42")

错误:

java.lang.NullPointerException: null

2 个答案:

答案 0 :(得分:6)

您在这里有两个不同的问题。在第一个示例中,您尝试在类CljHelper上调用方法。您应该在实例而非类上调用它。

(.test (CljHelper.) "This is a test")

对于第二个示例,您有一组额外的括号。因此,您正确地调用了方法test,但是随后您获取的结果为null,并尝试将其作为函数调用。因此,只需删除括号即可。

(defn add-id
  [x]
  (let [c (CljHelper.)]
    (.test c x)))

答案 1 :(得分:4)

这是最简单的方法。制作一个Java类Calc:

package demo;

public class Calc {
  public int answer() {
    return 42;
  } 
}

并从Clojure调用它:

(ns tst.demo.core
  (:use tupelo.core tupelo.test)
  (:import [demo Calc]))

(let [c (Calc.)]                   ; construct an instance of Calc
  (println :answer (.answer c)))   ; call the instance method

结果:

:answer 42

您可以clone a template Clojure project开始使用。

相关问题