从clojure处理java对象

时间:2013-03-01 16:50:08

标签: clojure functional-programming clojurescript clojure-contrib

是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端并且< em>访问到名字,姓氏等值......

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

问候,贺拉斯

2 个答案:

答案 0 :(得分: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 interop的示例。绝不是你应该编写这样的真实程序,特别是如果它们主要是在Clojure中。

答案 1 :(得分: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