简体   繁体   English

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

[英]How can I get the methods of a Java class from Clojure?

How can I get the methods of a Java class from Clojure?如何从 Clojure 获得 Java class 的方法?

[EDIT 2] [编辑 2]

Per M Smith's comment below, this accomplishes the same but provides sorting by method name and only returns methods:根据 M Smith 在下面的评论,这完成了相同的操作,但提供了按方法名称排序并且只返回方法:

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

[/EDIT 2] [/编辑 2]

[EDIT] [编辑]

My original answer refers to Clojure 1.2, but things have changed with Clojure 1.3.我最初的答案是指 Clojure 1.2,但随着 Clojure 1.3 的出现,情况发生了变化。 This works without any reliance on Clojure's contrib libraries now:现在可以在不依赖 Clojure 的 contrib 库的情况下工作:

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

(print-table (:members (r/reflect "foo")))

This provides a much more decoupled approach, with the reflect function providing all kinds of information on the argument passed in (in this case, a String "foo" ) and the print-table function taking any generic tabular data structure and pretty printing it as such.这提供了一种更加解耦的方法, reflect function 提供有关传入参数的各种信息(在本例中为String "foo" ), print-table function 采用任何通用表格数据结构并将其打印为这样的。

This is originally from this thread on the Google Group .这最初来自Google Group 上的这个帖子

[/EDIT] [/编辑]

I'd use the show function in the clojure.contrib.repl-utils namespace, which will print all static and instance members for an object (or class of an object). I'd use the show function in the clojure.contrib.repl-utils namespace, which will print all static and instance members for an object (or class of an object). I require it like so:我需要这样:

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

Here's an example using Joda Time:这是使用 Joda Time 的示例:

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

The first example demonstrates how you can simply pass a class to show , while the second demonstrates that you can pass an instance of the class as well.第一个示例演示如何简单地将 class 传递给show ,而第二个示例演示您也可以传递 class 的实例。

This of course works for lots of Clojure items that are Java classes underneath.这当然适用于许多 Clojure 项目,这些项目是 Java 类。 Here's an example of seeing all methods available to an instance of java.lang.String:这是查看 java.lang.String 实例可用的所有方法的示例:

(ru/show "foo")

Tryclojure.reflect , available in recent Clojure 1.3.0-alpha* releases.尝试clojure.reflect ,在最近的 Clojure 1.3.0-alpha* 版本中可用。 It returns Clojure data structures that you can search/filter as needed.它返回 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}}
...

You can use this method that uses clojure.reflect and extends the previous answers:您可以使用这种使用 clojure.reflect 的方法并扩展先前的答案:

(use 'clojure.reflect)

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

Usage:用法:

 (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)

This code will print all public methods, both declared and inherited.此代码将打印所有公共方法,包括声明的和继承的。

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

this will return Java array of declared methods:这将返回声明方法的 Java 数组:

(:declaredMethods (bean String))

(seq (:declaredMethods (bean String)))

advantage is bean is in clojure.core优点是 bean 在 clojure.core

Try my new library:试试我的新图书馆:

http://github.com/zcaudate/iroh http://github.com/zcaudate/iroh

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM