【问题标题】:How can I get the methods of a Java class from Clojure?如何从 Clojure 获取 Java 类的方法?
【发布时间】:2011-08-14 20:16:06
【问题描述】:

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

【问题讨论】:

    标签: clojure


    【解决方案1】:

    [编辑 2]

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

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

    [/EDIT 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 函数采用任何通用表格数据结构和漂亮的打印出来。

    这最初来自this thread on the Google Group

    [/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,而第二个示例则演示了您也可以传递该类的一个实例。

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

    (ru/show "foo")
    

    【讨论】:

    • (print-table (sort-by :name (:members (r/reflect "foo")))) 将对表格进行排序,使其更易于阅读
    • (print-table (sort-by :name (filter :exception-types (:members (r/reflect "foo"))))) 将按方法名称排序,使表格更易于阅读。它只返回方法,不返回成员变量。
    • 与“新”贡献者:(clojure.pprint/print-table (sort-by :name (filter :exception-types (:members (clojure.reflect/reflect "foo")))))
    【解决方案2】:

    试试clojure.reflect,在最近的 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}}
    ...
    

    【讨论】:

      【解决方案3】:

      您可以使用这种使用 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)
      

      【讨论】:

        【解决方案4】:

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

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

        【讨论】:

          【解决方案5】:

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

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

          优势是bean在clojure.core中

          【讨论】:

            【解决方案6】:

            试试我的新库:

            http://github.com/zcaudate/iroh

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

            【讨论】:

              猜你喜欢
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2016-10-19
              • 2013-04-17
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              相关资源
              最近更新 更多