Skip to content

Instantly share code, notes, and snippets.

@sunng87
Created November 20, 2015 10:04
  • Star 29 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
Star You must be signed in to star a gist
Save sunng87/13700d3356d5514d35ad to your computer and use it in GitHub Desktop.
clojure: access private field/method via reflection
(defn invoke-private-method [obj fn-name-string & args]
(let [m (first (filter (fn [x] (.. x getName (equals fn-name-string)))
(.. obj getClass getDeclaredMethods)))]
(. m (setAccessible true))
(. m (invoke obj args))))
(defn private-field [obj fn-name-string]
(let [m (.. obj getClass (getDeclaredField fn-name-string))]
(. m (setAccessible true))
(. m (get obj))))
@csakoda
Copy link

csakoda commented Feb 7, 2017

Thank you!

@ylgrgyq
Copy link

ylgrgyq commented Jun 22, 2017

调用 invoke 之前 args 是不是要转换为 array ?

@aaronblenkush
Copy link

I had to wrap args into an Object array to make this work. Line 5:

(. m (invoke obj (into-array Object args)))

@holyjak
Copy link

holyjak commented Oct 26, 2021

This variant also looks for fields in parent classes:

(defn private-field [obj field-name-string]
    (when-let [f (some
                   #(try (.getDeclaredField % field-name-string)
                         (catch NoSuchFieldException _ nil))
                   (take-while some? (iterate #(.getSuperclass %) (.getClass obj))))]
      (. f (setAccessible true))
      (. f (get obj))))

@lowecg
Copy link

lowecg commented Mar 21, 2023

As above, but with type hints to prevent reflection warnings against the implementation:

(set! *warn-on-reflection* true)

(import (java.lang.reflect Field))

(defn private-field [^Object obj ^String field-name]
  (when-let [^Field f (some
                        (fn [^Class c]
                          (try (.getDeclaredField c field-name)
                               (catch NoSuchFieldException _ nil)))
                        (take-while some? (iterate (fn [^Class c] (.getSuperclass c)) (.getClass obj))))]
    (. f (setAccessible true))
    (. f (get obj))))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment