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

如何从Clojure获得Java类的方法?,clojure,Clojure,如何从Clojure获取Java类的方法?此代码将打印所有公共方法,包括声明的和继承的 (doseq [m (.getMethods (type "Hello"))] (println "Method Name: " (.getName m)) (println "Return Type: " (.getReturnType m) "\n")) [编辑2] 根据M Smith下面的评论,这实现了相同的功能,但提供了按方法名称排序的功能,并且只返回方法: (print-table (

如何从Clojure获取Java类的方法?

此代码将打印所有公共方法,包括声明的和继承的

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

[编辑2]

根据M Smith下面的评论,这实现了相同的功能,但提供了按方法名称排序的功能,并且只返回方法:

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

[编辑]

我最初的答案是指Clojure1.2,但Clojure1.3的情况发生了变化。这项工作现在不依赖Clojure的contrib库:

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

(print-table (:members (r/reflect "foo")))
这提供了一种更加解耦的方法,
reflect
函数提供了有关传入参数的各种信息(在本例中,是一个
字符串
),而
print table
函数采用任何通用的表格数据结构并将其打印出来

这本来是从

[/EDIT]

我将使用
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
,而第二个示例演示也可以传递该类的实例

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

(ru/show "foo")
Try,在最近的Clojure 1.3.0-alpha*版本中提供。它返回Clojure数据结构,您可以根据需要进行搜索/筛选

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)

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

(:declaredMethods (bean String))

(seq (:declaredMethods (bean String)))
优点是bean在clojure中。core

试试我的新库:

(打印表(排序方式:名称(:members(r/reflect“foo”)))
将对表进行排序,使其更易于阅读
(打印表(排序方式:名称(筛选器:异常类型(:members(r/reflect“foo”)))
将按方法名称进行排序,使表更易于阅读。它只返回方法,不返回成员变量。使用“new”contrib:
(clojure.pprint/print-table(排序方式:名称(筛选器:异常类型)(:members(clojure.reflect/reflect“foo”)))
(.? String  #"^c" :name)
;;=> ["charAt" "checkBounds" "codePointAt" "codePointBefore"
;;    "codePointCount" "compareTo" "compareToIgnoreCase".   
;;    "concat" "contains" "contentEquals" "copyValueOf"]