I am trying to find a Clojure-idiomatic way to initialize a Java object. I have the following code:
(let [url-connection
(let [url-conn (java.net.HttpURLConnection.)]
(doto url-conn
(.setDoInput true)
; more initialization on url-conn
)
url-conn)]
; use the url-connection
)
but it seems very awkward.
What is a better way to create the HttpURLConnection
object and initialize it before using it later in the code?
UPDATE: It seems that (doto ...)
may come in handy here:
(let [url-connection
(doto (java.net.HttpURLConnection.)
(.setDoInput true)
; more initialization
))]
; use the url-connection
)
According to the doto
docs, it returns the value to which it is "doing".
Clojure solved this new language library problem by running on the JVM and having interoperability with Java classes. When you use Clojure, you can use Java classes and Java libraries. Clojure builds on the strength of the production-hardened and tested JVM and existing Java libraries.
Clojure programs get compiled to Java bytecode and executed within a JVM process. Clojure programs also have access to Java libraries, and you can easily interact with them using Clojure's interop facilities.
You can call a static method using (ClassName/methodName arguments) . However class is not a static method, it's a java keyword and you don't need it in clojure. To get the Class object associated with the String class, just use String . Save this answer.
As explained in the update to my question, here is the answer I came up with:
(let [url-connection
(doto (java.net.HttpURLConnection.)
(.setDoInput true)
; more initialization
))]
; use the url-connection
)
Maybe someone can come up with a better one.
Assuming that there is no constructor that accepts all the initialization parameters needed, then the way you did it is the only one I know.
The one thing you could do is wrap it all in a function like this:
(defn init-url-conn [doInput ...other params..]
(let [url-conn (java.net.HttpURLConnection.)]
(doto url-conn
(.setDoInput true)
; more initialization on url-conn
)
url-conn))
And call with:
(let [url-connection
(let [url-conn (init-url-con true ...other params..)]
; use the url-connection
)
However, this is specific per object and it is really useful only if you are initializing object of that class more than once.
Also you could write a macro that accepts all method names, and params and does this. But, when called, that call wouldn't be much shorter than your first example.
If anyone has a better idea, I'd like to see it, since I was asking myself the same just the other day..
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With