我如何从Clojure中获得Java类的方法?

我如何从Clojure中获得Java类的方法?

[编辑2]

Per M Smith的评论如下,这完成了相同的function,但是提供了按方法名称sorting并且只返回方法:

(print-table (sort-by :name (filter :exception-types (:members (r/reflect "foo"))))) 

[/编辑2]

[编辑]

我原来的答案是指Clojure 1.2,但是Clojure 1.3已经改变了。 这现在没有任何依赖Clojure的contrib库:

 (require '[clojure.reflect :as r]) (use '[clojure.pprint :only [print-table]]) (print-table (:members (r/reflect "foo"))) 

这提供了一个更多的解耦方法, reflect函数提供了有关参数(在本例中是一个String "foo" )的参数的各种信息,以及采用任何通用表格数据结构的print-table函数,并将其打印为这样。

这是最初来自Google群组的这个主题 。

[/编辑]

我将使用clojure.contrib.repl-utils命名空间中的show函数,它将打印对象(或对象的类)的所有静态和实例成员。 我需要这样的:

 (require '[clojure.contrib.repl-utils :as ru]) 

以下是使用Joda Time的例子:

 (import 'org.joda.time.DateTime) (ru/show DateTime) (ru/show (DateTime.)) 

第一个例子演示了如何简单地传递一个类来show ,而第二个例子演示了你可以传递类的一个实例。

这当然适用于下面的Java类的Clojure项目。 以下是查看java.lang.String实例可用的所有方法的示例:

 (ru/show "foo") 

尝试clojure.reflect ,在最近的Clojure 1.3.0-alpha *版本中可用。 它返回Clojure数据结构,您可以根据需要search/过滤。

 Clojure 1.3.0-alpha6 user=> (use 'clojure.reflect 'clojure.pprint) nil user=> (pprint (reflect "hello")) {:bases #{java.io.Serializable java.lang.Comparable java.lang.Object java.lang.CharSequence}, :flags #{:public :final}, :members #{{:name valueOf, :return-type java.lang.String, :declaring-class java.lang.String, :parameter-types [boolean], :exception-types [], :flags #{:static :public}} ... 

你可以使用这个方法,使用clojure.reflect并扩展以前的答案:

 (use 'clojure.reflect) (defn all-methods [x] (->> x reflect :members (filter :return-type) (map :name) sort (map #(str "." %) ) distinct println)) 

用法:

  (all-methods "") ; => (.charAt .checkBounds .codePointAt .codePointBefore .codePointCount .compareTo .compareToIgnoreCase .concat .contains .contentEquals .copyValueOf .endsWith .equals .equalsIgnoreCase .format .getBytes .getChars .hashCode .indexOf .intern .isEmpty .lastIndexOf .length .matches .offsetByCodePoints .regionMatches .replace .replaceAll .replaceFirst .split .startsWith .subSequence .substring .toCharArray .toLowerCase .toString .toUpperCase .trim .valueOf) (all-methods 1) ; => (.bitCount .byteValue .compareTo .decode .doubleValue .equals .floatValue .getChars .getLong .hashCode .highestOneBit .intValue .longValue .lowestOneBit .numberOfLeadingZeros .numberOfTrailingZeros .parseLong .reverse .reverseBytes .rotateLeft .rotateRight .shortValue .signum .stringSize .toBinaryString .toHexString .toOctalString .toString .toUnsignedString .valueOf) (all-methods java.util.StringTokenizer) ; => (.countTokens .hasMoreElements .hasMoreTokens .isDelimiter .nextElement .nextToken .scanToken .setMaxDelimCodePoint .skipDelimiters) 

这段代码将打印所有公开的方法,声明和inheritance。

 (doseq [m (.getMethods (type "Hello"))] (println "Method Name: " (.getName m)) (println "Return Type: " (.getReturnType m) "\n")) 

这将返回已声明方法的Java数组:

 (:declaredMethods (bean String)) (seq (:declaredMethods (bean String))) 

优点是豆在clojure.core

试试我的新库:

http://github.com/zcaudate/iroh

 (.? String #"^c" :name) ;;=> ["charAt" "checkBounds" "codePointAt" "codePointBefore" ;; "codePointCount" "compareTo" "compareToIgnoreCase". ;; "concat" "contains" "contentEquals" "copyValueOf"]