4

我是 clojure 的新手,想使用 clojure 与 java 对象进行交互。如果我很好理解,可以使用defprotocol来实现这种交互。我具体尝试做的是以下内容:

1-我有以下java类

package mytestspackage;

public class TestObject {

    private String lastName;
    private String firstName;
    private String age;

    public TestObject(String lastName, String firstname, String age) {
        super();
        this.lastName = lastName;
        this.firstName = firstname;
        this.age = age;
    }

    public String getName() {
        return this.lastName;
    }

    public void setName(String name) {
        this.lastName = name;
    }

    public String getFirstname() {
        return this.firstName;
    }

    public void setFirstname(String vorname) {
        this.firstName = vorname;
    }

    public String getAge() {
        return this.age;
    }

    public void setAge(String age) {
        this.age = age;
    }

}

2-我创建了一个 clojure 协议,它应该允许我访问上述 java 类TestObject的实例

(ns mytestspackage)
(defprotocol Test
  (first-name [t])
  (last-name [t])
  (age [t]))

现在我的问题是:我在哪里具体实现协议中定义的方法以及如何使用此实现将 TestObject 实例传递到 clojure 端并访问名字、姓氏等值...

任何帮助,将不胜感激。提前致谢。

问候,贺拉斯

4

2 回答 2

3

如果我很好理解的话,可以使用 defprotocol 来实现这种交互。

不,你搞错了。协议旨在允许类似于普通 java 中的接口允许的事情(尽管更强大)。您可以在没有任何协议的情况下访问您的 Java 类。关于这个主题的官方 clojure 文档:http: //clojure.org/java_interop

例子:

(ns example
  (:import mytestpackage.TestObject))

;; This is how we call methods on java objects    

(defn first-name [obj]
  (.getFirstname obj))

(defn last-name [obj]
  (.getName obj))

(defn age [obj]
  (.getAge obj))

(defn set-first-name [obj name]
  (.setFirstname obj name))

(defn set-last-name [obj name]
  (.setName obj name))

(defn set-age [obj age]
  (.setAge obj age))

;; In REPL

example => (let [x (TestObject. nil nil nil)      ;; This is how we create Java objects
                 x (new TestObject nil nil nil)]  ;; These expressions are equivalent
              (println (first-name x))
              (set-first-name x "Name")
              (println (first-name x))
              (set-last-name x "Last name")
              (set-age x "23")
              (println (last-name x))
              (println (age x)))
;; Outputs
nil
Name
Last name
23

请注意,此代码只不过是旨在介绍 java 互操作的示例。绝不应该编写这样的真实程序,尤其是如果它们主要是在 Clojure 中。

于 2013-03-01T17:27:20.770 回答
1

如果您只想使用 Clojure 与 java 对象进行交互,而不是在它们上实现新功能,则无需担心协议。Clojure 为 java 方法调用提供直接访问和语法。

例如 Clojure 中的字符串是 java.lang.String 对象:

user=> (type "Really a Java String")
;; java.lang.String

user=> (.toUpperCase "Really a java string")
;;=> "REALLY A JAVA STRING"

如果您的测试对象类在类路径上,您可以像这样创建实例:

user=> (def a-test-object (mytestpackage/TestObject. "lastName" "firstName" 42))

并调用如下方法:

user=> (.getAge a-test-object)

有关详细信息,请参阅http://clojure.org/java_interop

于 2013-03-01T17:39:03.140 回答