Skip to content

Instantly share code, notes, and snippets.

@ryoakg
Forked from athos/apply_ctor.clj
Last active June 29, 2016 15:12
Show Gist options
  • Save ryoakg/77ee883467144a82d93bad537055446c to your computer and use it in GitHub Desktop.
Save ryoakg/77ee883467144a82d93bad537055446c to your computer and use it in GitHub Desktop.
引数は同じで、コンストラクタを可変にしたい場合
(ns apply-ctor
(import [java.lang.reflect Constructor]))
(defn- acceptable-types? [ptypes atypes]
(and (= (count ptypes) (count atypes))
(every? (fn [[ptype atype]]
(or (= ptype atype)
((ancestors atype) ptype)))
(map vector ptypes atypes))))
(defn apply-ctor [^Class klass args]
(let [atypes (into-array Class (map class args))
ctors (for [^Constructor ctor (.getConstructors klass)
:let [ptypes (.getParameterTypes ctor)]
:when (acceptable-types? ptypes atypes)]
ctor)]
(when (empty? ctors)
(throw (IllegalArgumentException.
(str "No matching ctor found for " klass))))
(let [^"[Ljava.lang.Object;" args (into-array Object args)]
(.newInstance ^Constructor (first ctors) args))))
(defn f1 [c args] (eval `(new ~c ~@args)))
(defn f2 [c args] (apply-ctor c args))
(time (dotimes [i 10000] (f1 String [(str "hoge" i)])))
;; "Elapsed time: 4497.773954 msecs"
(time (dotimes [i 10000] (f2 String [(str "hoge" i)])))
;; "Elapsed time: 461.229971 msecs"
@ryoakg
Copy link
Author

ryoakg commented Jun 29, 2016

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