2013-04-10 25 views
8

我需要以某種方式將某些Clojure函數標記爲「特殊」,以便Java代碼可以使用反射來識別它們。我試圖給函數添加註釋,但顯然不支持。我試過reify一個擴展爲IFn的接口(以便Java代碼可以識別函數對象),但這並不好,因爲Clojure沒有直接使用實現方法作爲實現invoke的代碼,而是直接調用Afunction實際實現該方法的對象(我需要用實際功能代碼標記實際的invoke方法)。我如何標記一個Clojure函數,以便我可以用Java反射識別它

任何想法?

編輯:甚至可以用ASM庫(而不是常規反射)訪問的方式標記會很好,但我需要以某種方式標記實際的AFunction對象或invoke方法。另外,我無法訪問實際的AFunction對象 - 我需要該標記在課程中可見。

回答

3

可以使用的Clojure元數據功能,它允許元數據(地圖),以附接至實現IMeta接口(其結果是每一個對象作爲IObj延伸IMeta和每一個對象延伸IObj)任何對象

現在有2個選項。

1)您可以將元數據附加到VAR(風險價值指向實際IFN對象)

(defn hello {:name "hello"} [] 10) 

,並在Java方面你得到的VAR打招呼的持有和使用IMeta方法來獲取元數據並檢測您的特定元數據是否存在。 這個問題可能是你的Java代碼直接訪問/處理IFn對象而不是它們的變量(例如:匿名函數),爲了解決這個問題,試試第二種方法。

2)安裝元數據的功能對象本身:

(def hello (with-meta (fn [] 10) {:name "hello"})) 

不能使用defn作爲元數據附加到變量。上面的示例代碼將元數據附加到函數對象本身。在Java方面,將函數對象轉換爲IMeta並執行檢查。 上面的代碼可以做得更多defn比較與作爲一個練習剩下的宏的幫助:)

+0

謝謝!不幸的是,我甚至無法訪問IFn對象 - 僅限於它的類。我需要以某種方式標記這個類(我甚至不需要附加任何特定的信息,只是以某種方式確定該類是否被「標記」)。我想通過讓invoke方法指定它引發一個衆所周知的檢查異常來標記它,但是我不知道從Clojure那裏做這件事。 – pron 2013-04-10 12:44:35

+0

你能否提供一些clojure和java的示例代碼來展示如何從clojure創建類並從Java訪問,因爲這會使問題更加清晰 – Ankur 2013-04-10 12:46:23

+0

我使用JavaAgent來測試某些類。我會在加載新課程時收到通知。我想以某種方式標記Clojure函數,以便知道它是否需要檢測。 – pron 2013-04-10 12:48:41

0

事實證明,如果你用一個包含本地定義的let語句包含函數體,變量名將出現在類文件的方法本地表中。雖然有點麻煩。仍在尋找更好的方法。

相關問題