clojure實現java類
為什麼需要這麼幹?因為clojure可以調用java的類,但有時候這些java類需要你實現一個子類或者傳遞一個自訂的java對象作為參數,所以需要將clojure代碼編譯成java代碼。
還記得之前提過的:gen-class麼,在(ns...)中,使用(:gen-class),在(ns..)之外,應該用 (gen-class)
下面是一個例子, 檔案MoveDailyAction.clj內容如下:
(ns kafka2hdfs.MoveDailyAction (:import [org.apache.hadoop.fs FileSystem Path] [java.io.IOException] [java.text DateFormat SimpleDateFormat] [java.util.Date]))(gen-class :name kafka2hdfs.MoveDailyAction :implements [org.apache.storm.hdfs.common.rotation.RotationAction] :state dest :init init :constructors {[String][]})(defn -init [dest] [[] dest])
這個類名叫MoveDailyAction,實現了RotationAction介面,有一個不可變的公有成員變數dest, 有一個init成員函數會在建構函式內部被調用。建構函式不需要實現,只需要聲明參數形式。
為了在lein項目中,運行lein repl時自動載入並編譯該類,需要在project.clj中的:aot中添加, 注意core.clj依賴MoveDailyAction.class,所以需要將MoveDailyAction放在前面先編譯
:aot [kafka2hdfs.MoveDailyAction kafka2hdfs.core]
這裡體會到:aot的用處了,就是需要將clojure代碼提前編譯成java class,然後用於其他地方。
在repl中運行下面的代碼測試:
kafka2hdfs.core=> (def o (kafka2hdfs.MoveDailyAction. ab))#'kafka2hdfs.core/okafka2hdfs.core=> (.dest o)ab
建構函式接受的參數,在後面可以讀取出來。