Skip to content

Instantly share code, notes, and snippets.

@karatatar
Forked from scotthaleen/new-instance.clj
Created June 20, 2019 11:17
Show Gist options
  • Select an option

  • Save karatatar/2976660bebb2acaa005a7fe5436d3b70 to your computer and use it in GitHub Desktop.

Select an option

Save karatatar/2976660bebb2acaa005a7fe5436d3b70 to your computer and use it in GitHub Desktop.
Clojure dynamically create new instances of a Class
(defn new-instance
" creates a new Instance of a Class
Passing a Class will result in Class.newInstance
(new-instance String)
Passing a Class and vector of args will attempt to match the Constructor
by creating a Class[] by calling `class` on each arg
String.getConstructor(new Class[]{String}).newInstance(new Object[]{\"abc\"})
(new-instance String [\"abc\"])
Sometimes you need to be more granular in the Class matching
Passing Class vector-of-classes and args which much match the class is in
vector-of-classes
Long.getConstructor(new Class[]{long}).newInstance(new Object[]{42})
(new-instance [Long/TYPE] [42])
"
([clazz]
(. clazz newInstance))
([clazz args]
(new-instance clazz (map class args) args))
([clazz ctor-classes args]
(->
(. clazz getConstructor (into-array Class ctor-classes))
(.newInstance (into-array Object args)))))
(comment
(new-instance String)
;;=> ""
(new-instance (class "abc"))
;;=> ""
(new-instance String ["foo"])
;;=> "foo"
(new-instance Long [String] ["11"])
;;=> 11
(new-instance Long [Long/TYPE] [42])
;;=> 11
(new-instance java.io.File [(clojure.java.io/file "/tmp") "test.txt"])
;;=> #object[java.io.File 0x5c69702f "/tmp/test.txt"]
(new-instance java.io.File ["/tmp" "test2.txt"])
;;=> #object[java.io.File 0x39859951 "/tmp/test2.txt"]
)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment