Some simplified examples of how to read Java and turn it into Clojure. Intended for Clojurists without a background in Java. Based on clojure.org's Java Interop reference.
Consider reading: https://stackoverflow.com/questions/11993077/difference-between-static-methods-and-instance-methods
Say we come across some Java that calls a method on a string literal:
String s = "fred";
System.out.println(s.toUpperCase());
-> "FRED"This is called invoking an instance member (toUpperCase) of an instance (s) of a class (String). We can look up the Javadoc and see that toUpperCase is listed as a Method that is called on a String and which returns a String.
Because we're calling a method of the String class on an instance of a String, we use the instance member macro to implement the same call in Clojure. The syntax is: (.instanceMember instance args*)
For example:
(.toUpperCase "fred")
-> "FRED"We can use the same syntax when invoking an instance member of a class name: (.instanceMember Classname args*)
For example, we can get the name of the String class name itself, with getName:
String.class.getName()
-> "java.lang.String"In Clojure:
(.getName String)
-> "java.lang.String"Sometimes we'll come across Java that calls a method directly from the class, instead of on an instance of that class. For instance, the getProperty method of System is listed as a static method, so in Java, it is called directly on the System class:
System.getProperty("java.vm.version");
-> "1.6.0_07-b06-57"Notice how getProperty has "static" under the "Modifier" column of the Javadoc's Method Summary, and its Method Detail lists it as public static String getProperty(String key). Because it is static, getProperty belongs to the System class itself, not to an instance of the System class. This means it is called from System itself rather than from a System object we create.
The Clojure translation of calling static methods uses slash syntax: (Classname/staticMethod args*), which makes the difference from calling instance members more obvious:
(System/getProperty "java.vm.version")
-> "1.6.0_07-b06-57"Sometimes--though not often--Java objects allow you to directly read the values of their member fields. (More often, you're forced to use a "getter" method to read the value.) For instance we can get the x value of a Point object using Java:
Point p = new Point(4,6);
p.x;
-> 4The Javadoc tells us that x is a Field of Point, rather than a Method such as getX. This is also hinted by the fact that p.x ends with no parentheses.
The Clojure syntax for an instance field is a dot-dash: (.-instanceField instance) (In Clojure's Java interop, a dash prefix indicates field access.) So the above Java translated to Clojure looks like:
(.-x (java.awt.Point. 4 6))
-> 4(Notice that we omit the comma, because commas are optional whitespace in Clojure. Most folks only include them to mark pairs in hard-to-read maps.)
Finally, we might need to read the value of a class's field. These are called static fields. For instance, we get the value of Pi directly from the Math class, without creating an object of class Math:
Math.PI
-> 3.141592653589793The Clojure syntax for this is Classname/staticField, so translating the Pi example above is:
Math/PI
-> 3.141592653589793