【问题标题】:Invoke non-static Java method in Clojure在 Clojure 中调用非静态 Java 方法
【发布时间】:2020-06-10 22:35:58
【问题描述】:

在 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

【问题讨论】:

  • 删除外部括号 ((.test c x)) - 你调用的是测试结果,它是 nil - 括号总是有意义的,不能像花括号语言那样添加以使事情更清楚。
  • 是的,你是对的;有一组额外的括号。

标签: java clojure interop


【解决方案1】:

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

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

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

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

【讨论】:

  • 是的,这两个问题的建议解决方案都有效。谢谢
【解决方案2】:

这是最简单的方法。制作一个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 开始使用。

【讨论】:

  • 谢谢艾伦。我已经实施了您的解决方案。 Java 方法被执行,但它立即抛出 java.lang.NullPointerException: null.
  • 将您当前的代码添加到问题中。您可能忘记在c 之后添加text
  • 我已经删除了额外的括号集,如上面的答案所述,现在可以使用了。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-01-03
  • 1970-01-01
  • 2015-06-17
  • 1970-01-01
相关资源
最近更新 更多