Learning Clojure/Calling Java

From Wikibooks, open books for an open world
Jump to: navigation, search
  • (. instance method args*)
  • (. class method args*)

The special form . also known as host, invokes a public Java method or retrieves the value of a public Java field:

(. foo bar 7 4)   ; call the method bar of the instance/class foo with arguments 7 and 4
(. alice bob)     ; return the value of public field bob of the instance/class alice

Notice that accessing a field might be mistaken for invoking a parameter-less method: if a class has a parameter-less method and public field of the same name, the ambiguity is resolved by assuming that calling the method is what's intended.

If the first argument to . is a symbol, the symbol is evaluated specially: if the symbol resolves to a Class referred in the current namespace, then this is a call to one of that Class's static methods; otherwise, this is a call to a method of the instance resolved from the symbol. So confusingly, using . with a non-referred symbol resolving to a Class is an invocation of a method of that Class object, not an invocation of a static method of the class represented by that Class object:

(. String valueOf \c)   ; invoke the static method String.valueOf(char) with argument 'c'
(def ned String)        ; interned Var mapped to ned now holds the Class of String
(. ned valueOf \c)      ; exception: attempt to call Class.valueOf, which doesn't exist

While the . operator is the generic operator for accessing java, there are more readable reader macros that should be preferred instead of using . directly:

  • (.field instance args*)
  • Class/StaticField or (Class/StaticMethod args*)

Note: Prior to Subversion revision 1158, .field was also usable for static access. However, in recent versions of Clojure, a (.field ClassName) form is treated as if ClassName were the corresponding instance of class java.lang.Class.

Thus, the above examples would be written as:

(String/valueOf \c)    ; Static method access!
(def ned String)
(.valueOf ned \c)      ; This will fail
(.valueOf String \c)   ; And in recent versions, so will this.

If there is need to manipulate the Class object, for example to call the Class.newInstance method, one can do the following:

(. (identity String) newInstance "fred")   ; will create a new instance; this will work in all versions of clojure
(.newInstance String "fred")               ; will work only in a recent enough version of clojure. Expands to the above form.
(.newInstance (identity String) "fred")    ; this was required in old versions


  • (new class args*)

The special form new instantiates a Java class, calling its constructor with the supplied arguments:

(new Integer 3)    ; instantiate Integer, passing 3 as argument to the constructor

Like with calling static methods with ., the class must be specified as a symbol, not as the Class object of the class you wish to instantiate:

(new String "yo")   ; new String("yo")
(def ned String)    ; interned Var mapped to ned now holds the Class of String
(new ned "yo")      ; exception: new Class("yo") is invalid

A reader macro exists for new as well:

  • (Classname. args*)
(String. "yo")      ; equivalent to (new String "yo"). Notice the dot!
« Learning Clojure
Calling Java
»
Branching and Monads Building Jars