在 Clojure 中调用非静态 Java 方法

Edu*_* MC 3 java interop clojure

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

Java类:

public class CljHelper {

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

}
Run Code Online (Sandbox Code Playgroud)

Clojure 代码:

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

(. CljHelper test "This is a test")  
Run Code Online (Sandbox Code Playgroud)

错误:

java.lang.IllegalArgumentException: No matching method: test
Run Code Online (Sandbox Code Playgroud)

这是另一种尝试,它使 Java 方法被执行,但在之后立即抛出错误:

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

(add-Id "id42")
Run Code Online (Sandbox Code Playgroud)

错误:

java.lang.NullPointerException: null
Run Code Online (Sandbox Code Playgroud)

小智 6

You have two different issues here. In the first example you're trying to invoke a method on the class CljHelper. You should be calling it on the instance, not the class.

(.test (CljHelper.) "This is a test")
Run Code Online (Sandbox Code Playgroud)

For the second example, you have an extra set of parentheses. So, you're correctly calling the method test, but then you are taking the result, which is null, and attempting to call that as a function. So just remove the parentheses.

(defn add-id
  [x]
  (let [c (CljHelper.)]
    (.test c x)))
Run Code Online (Sandbox Code Playgroud)