Calling Java

Clojure provides simple, direct syntax for calling Java code: creating objects, invoking methods, and accessing static methods and fields. In addition, Clojure provides syntactic sugar that makes calling Java from Clojure more concise than calling Java from Java!

Not all types in Java are created equal: the primitives and arrays work differently. Where Java has special cases, Clojure gives you direct access to these as well. Finally, Clojure provides a set of convenience functions for common tasks that would be unwieldy in Java.

The first step in many Java interop scenarios is creating a Java object. Clojure provides the new special form for this purpose:

 (new classname)

Try creating a new Random:

 (new java.util.Random)
 -> #object[java.util.Random 0x30dae81 ​"java.util.Random@30dae81"​]

Another more frequently used shortcut for creating a new instance of a class is to append a trailing . to the class name:

 (java.util.Random.)
 -> #object[java.util.Random 0x133314b ​"java.util.Random@133314b"​]

The REPL simply prints out the new Random instance indicating its class, hash code, and the result of calling its toString method. To use a Random instance, you need to save it away somewhere. For now, simply use def to save the Random into a Clojure Var:

 (​def​ rnd (new java.util.Random))
 -> #​'user/rnd

Now you can call methods on rnd using Clojure’s dot (.) special form:

 (. class-or-instance member-symbol & args)
 (. class-or-instance (member-symbol & args))

The . can call methods. For example, the following code calls the no-argument version of nextInt:

 (. rnd nextInt)
 -> -791474443

Random also has a nextInt that takes an argument. You can call that version by adding the argument to the list:

 (. rnd nextInt 10)
 -> 8

The . syntax can also be used to access instance fields, static methods, and static fields:

 ;; Instance field
 (​def​ p (java.awt.Point. 10 20))
 (. p x)
 -> 10
 
 ;; Static method
 (. System lineSeparator)
 -> ​" "
 
 ;; Static field
 (. Math PI)
 -> 3.141592653589793

In cases where there are both a method and a field of the same name, the method will be preferred. The member name can be prefixed with a - to apply only to fields:

 ;; Instance field
 (​def​ p (java.awt.Point. 10 20))
 (. p -x)
 -> 10
 
 ;; Static field
 (. Math -PI)
 -> 3.141592653589793

However, Clojure also provides a more concise syntax for both instance and static access that is preferred:

 (.method instance & args)
 (.field instance)
 (.-field instance)
 (Class/method & args)
 Class/field

Rewriting the examples above with the more concise style looks like this:

 (.nextInt rnd 10)
 -> 8
 
 (.x p) ​;; or (.-x p)
 -> 10
 
 (System/lineSeparator)
 -> ​" "
 
 Math/PI
 -> 3.141592653589793

Notice in the previous examples that Math is not fully qualified, because Clojure imports java.lang classes automatically. To avoid typing java.util.Random everywhere, you can import it:

 (import (package-symbol & class-name-symbols)*)

import takes a variable number of lists, with the first part of each list being a package name and the rest being names to import from that package. The following import allows unqualified access to Random, Locale, and MessageFormat:

 (import '(java.util Random Locale)
  '(java.text MessageFormat))
 -> java.text.MessageFormat
 
 Random
 -> java.util.Random
 
 Locale
 -> java.util.Locale
 
 MessageFormat
 -> java.text.MessageFormat

At this point, you have almost everything you need to call Java from Clojure. You can do the following:

  • Import class names
  • Create instances
  • Access fields
  • Invoke methods

However, there isn’t anything particularly exciting about the syntax. It’s just “Java with different parentheses.”

Although reaching into Java from Clojure is easy, remembering how all of the Java bits underneath work can be daunting. Clojure provides a javadoc function that will make your life much easier. This provides a pleasant experience from the REPL when exploring.

 (javadoc java.net.URL)
..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.221.151.71