在 Clojure 中调用非静态 Java 方法

Invoke non-static Java method in Clojure

在 Clojure 中调用静态 Java 方法很顺利;没问题。但是当我调用一个非静态方法时,它会抛出一个错误,尽管我已经尝试了几种点 (.) 表示法的变体,如 Clojure Interop documentation.

中所述

Java class:

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

这是最简单的方法。进行 java class 计算:

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开始。

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

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

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

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