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

Clojure

Clojure Problem Overview


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

Clojure Solutions


Solution 1 - Clojure

[EDIT 2]

Per M Smith's comment below, this accomplishes the same but provides sorting by method name and only returns methods:

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

[/EDIT 2]

[EDIT]

My original answer refers to Clojure 1.2, but things have changed with Clojure 1.3. This works without any reliance on Clojure's contrib libraries now:

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

This is originally from this thread on the 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 require it like so:

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

Here's an example using 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.

This of course works for lots of Clojure items that are Java classes underneath. Here's an example of seeing all methods available to an instance of java.lang.String:

(ru/show "foo")

Solution 2 - Clojure

Try clojure.reflect, available in recent Clojure 1.3.0-alpha* releases. It returns Clojure data structures that you can search/filter as needed.

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}}
...

Solution 3 - Clojure

You can use this method that uses clojure.reflect and extends the previous answers:

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

Solution 4 - Clojure

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

Solution 5 - Clojure

this will return Java array of declared methods:

(:declaredMethods (bean String))

(seq (:declaredMethods (bean String)))

advantage is bean is in clojure.core

Solution 6 - Clojure

Try my new library:

http://github.com/zcaudate/iroh

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

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionyazz.comView Question on Stackoverflow
Solution 1 - ClojuresemperosView Answer on Stackoverflow
Solution 2 - ClojureStuart SierraView Answer on Stackoverflow
Solution 3 - ClojurezcaudateView Answer on Stackoverflow
Solution 4 - ClojuredbyrneView Answer on Stackoverflow
Solution 5 - Clojurek1m190rView Answer on Stackoverflow
Solution 6 - ClojurezcaudateView Answer on Stackoverflow